diff --git a/products/terraform/docs/swfw/aws/cloudngfw/examples/panorama_standalone.md b/products/terraform/docs/swfw/aws/cloudngfw/examples/panorama_standalone.md index 5cccea735..69b347f46 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/examples/panorama_standalone.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/examples/panorama_standalone.md @@ -50,7 +50,7 @@ Example was prepared for PAN-OS in **10.2.3** version as described in [AWS Deplo 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` +5. Review `terraform.tfvars` file, especially with lines commented by ` # TODO: update here`. To deploy Panorama with NAT Gateway for outbound access, please refer to the `# NAT GW` comments in the file. 6. Initialize Terraform: `terraform init` 7. Prepare plan: `terraform plan` 8. Deploy infrastructure: `terraform apply -auto-approve` @@ -90,6 +90,7 @@ Use a web browser to access https://x.x.x.x and login with admin and your previo | Name | Source | Version | |------|--------|---------| +| [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | | [panorama](#module\_panorama) | ../../modules/panorama | n/a | | [subnet\_sets](#module\_subnet\_sets) | ../../modules/subnet_set | n/a | | [vpc](#module\_vpc) | ../../modules/vpc | n/a | @@ -111,10 +112,11 @@ Use a web browser to access https://x.x.x.x and login with admin and your previo |------|-------------|------|---------|:--------:| | [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `map(any)` | `{}` | no | | [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | `""` | no | -| [panoramas](#input\_panoramas) | A 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 | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | +| [panoramas](#input\_panoramas) | A 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({
name = optional(string)
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
force\_detach = optional(bool, false)
skip\_destroy = optional(bool, false)
}))
encrypted = bool
kms\_key\_alias = optional(string, "alias/aws/ebs")
})

product\_code = optional(string, "eclz7j04vu9lf8ont8ta3n17o")
include\_deprecated\_ami = optional(bool, false)
panorama\_ami\_id = optional(string)
instance\_type = optional(string, "c5.4xlarge")
enable\_monitoring = optional(bool, false)
eip\_domain = optional(string, "vpc")

iam = object({
create\_role = bool
role\_name = string
})

enable\_imdsv2 = optional(bool, false)
}))
| `{}` | no | | [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | -| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | -| [vpcs](#input\_vpcs) | A 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 | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | `""` | no | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | ### Outputs diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/alb.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/alb.md index f5374da72..773c94d25 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/alb.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/alb.md @@ -145,7 +145,7 @@ No modules. | [enable\_cross\_zone\_load\_balancing](#input\_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](#input\_idle\_timeout) | The time in seconds that the connection to the Load Balancer can be idle. | `number` | `60` | no | | [lb\_name](#input\_lb\_name) | Name of the Load Balancer to be created. | `string` | n/a | yes | -| [rules](#input\_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:
rules = {
"application\_name" = {
protocol = "communication protocol, since this is an ALB module accepted values are `HTTP` or `HTTPS`"
port = "communication port, defaults to protocol's default port"

certificate\_arn = "(HTTPS ONLY) this is the arn of an existing certificate, this module will not create one for you"
ssl\_policy = "(HTTPS ONLY) name of an ssl policy used by the Load Balancer's listener, defaults to AWS default, for available options see [AWS documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies)"

health\_check\_protocol = "this can be either `HTTP` or `HTTPS`, defaults to communication protocol"
health\_check\_port = "port used by the target group health check, if omitted, `traffic-port` will be used (which will be the same as communication port)"
health\_check\_healthy\_threshold = "number of consecutive health checks before considering target healthy, defaults to 3"
health\_check\_unhealthy\_threshold = "number of consecutive health checks before considering target unhealthy, defaults to 3"
health\_check\_interval = "time between each health check, between 5 and 300 seconds, defaults to 30s"
health\_check\_timeout = "health check probe timeout, defaults to AWS default value"
health\_check\_matcher = "response codes expected during health check, defaults to `200`"
health\_check\_path = "destination used by the health check request, defaults to `/`"

listener\_rules = "a map of rules for a listener created for this application, see `listener\_rules` block below for more information
}
}
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](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule#condition-blocks).

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:
listener\_rules = {
"rule\_priority" = { # string representation of a rule's priority (number from 1 - 50000)
target\_port = "port on which the target is listening for requests"
target\_protocol = "target protocol, can be `HTTP` or `HTTPS`"
protocol\_version = "one of `HTTP1`, `HTTP/2` or `GRPC`, defaults to `HTTP1`"

round\_robin = "bool, if set to true (default) the `round-robin` load balancing algorithm is used, otherwise a target attachment with least outstanding requests is chosen.

host\_headers = "a list of possible host headers, case insensitive, wildcards (`*`,`?`) are supported"
http\_headers = "a map of key-value pairs, where key is a name of an HTTP header and value is a list of possible values, same rules apply like for `host\_headers`"
http\_request\_method = "a list of possible HTTP request methods, case sensitive (upper case only), strict matching (no wildcards)"
path\_pattern = "a list of path patterns (w/o query strings), case sensitive, wildcards supported"
query\_strings = "a map of key-value pairs, key is a query string key pattern and value is a query string value pattern, case insensitive, wildcards supported, it is possible to match only a value pattern (the key value should be prefixed with `nokey\_`)"
source\_ip = "a list of source IP CDIR notation to match"
}
}


EXAMPLE
listener\_rules = {
"1" = {
target\_port = 8080
target\_protocol = "HTTP"
host\_headers = ["public-alb-1050443040.eu-west-1.elb.amazonaws.com"]
http\_headers = {
"X-Forwarded-For" = ["192.168.1.*"]
}
http\_request\_method = ["GET"]
}
"99" = {
host\_headers = ["www.else.org"]
target\_port = 8081
target\_protocol = "HTTP"
path\_pattern = ["/", "/login.php"]
query\_strings = {
"lang" = "us"
"nokey\_1" = "test"
}
source\_ip = ["10.0.0.0/8"]
}
}
| `any` | n/a | yes | +| [rules](#input\_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:
rules = {
"application\_name" = {
protocol = "communication protocol, since this is an ALB module accepted values are `HTTP` or `HTTPS`"
port = "communication port, defaults to protocol's default port"

certificate\_arn = "(HTTPS ONLY) this is the arn of an existing certificate, this module will not create one for you"
ssl\_policy = "(HTTPS ONLY) name of an ssl policy used by the Load Balancer's listener, defaults to AWS default, for available options see [AWS documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies)"

health\_check\_protocol = "this can be either `HTTP` or `HTTPS`, defaults to communication protocol"
health\_check\_port = "port used by the target group health check, if omitted, `traffic-port` will be used (which will be the same as communication port)"
health\_check\_healthy\_threshold = "number of consecutive health checks before considering target healthy, defaults to 3"
health\_check\_unhealthy\_threshold = "number of consecutive health checks before considering target unhealthy, defaults to 3"
health\_check\_interval = "time between each health check, between 5 and 300 seconds, defaults to 30s"
health\_check\_timeout = "health check probe timeout, defaults to AWS default value"
health\_check\_matcher = "response codes expected during health check, defaults to `200`"
health\_check\_path = "destination used by the health check request, defaults to `/`"

listener\_rules = "a map of rules for a listener created for this application, see `listener\_rules` block below for more information
}
}
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](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule#condition-blocks).

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:
listener\_rules = {
"rule\_priority" = { # string representation of a rule's priority (number from 1 - 50000)
target\_port = "port on which the target is listening for requests"
target\_protocol = "target protocol, can be `HTTP` or `HTTPS`"
protocol\_version = "one of `HTTP1`, `HTTP/2` or `GRPC`, defaults to `HTTP1`"

round\_robin = "bool, if set to true (default) the `round-robin` load balancing algorithm is used, otherwise a target attachment with least outstanding requests is chosen.

host\_headers = "a list of possible host headers, case insensitive, wildcards (`*`,`?`) are supported"
http\_headers = "a map of key-value pairs, where key is a name of an HTTP header and value is a list of possible values, same rules apply like for `host\_headers`"
http\_request\_method = "a list of possible HTTP request methods, case sensitive (upper case only), strict matching (no wildcards)"
path\_pattern = "a list of path patterns (w/o query strings), case sensitive, wildcards supported"
query\_strings = "a map of key-value pairs, key is a query string key pattern and value is a query string value pattern, case insensitive, wildcards supported, it is possible to match only a value pattern (the key value should be prefixed with `nokey\_`)"
source\_ip = "a list of source IP CDIR notation to match"
}
}


EXAMPLE
listener\_rules = {
"1" = {
target\_port = 8080
target\_protocol = "HTTP"
host\_headers = ["public-alb-1050443040.eu-west-1.elb.amazonaws.com"]
http\_headers = {
"X-Forwarded-For" = ["192.168.1.*"]
}
http\_request\_method = ["GET"]
}
"99" = {
host\_headers = ["www.else.org"]
target\_port = 8081
target\_protocol = "HTTP"
path\_pattern = ["/", "/login.php"]
query\_strings = {
"lang" = "us"
"nokey\_1" = "test"
}
source\_ip = ["10.0.0.0/8"]
}
}
|
map(object({
protocol = string
port = number
certificate\_arn = optional(string)
ssl\_policy = optional(string)
health\_check\_protocol = optional(string)
health\_check\_port = optional(string)
health\_check\_healthy\_threshold = optional(number)
health\_check\_unhealthy\_threshold = optional(number)
health\_check\_interval = optional(number)
health\_check\_timeout = optional(number)
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
listener\_rules = map(object({
target\_port = number
target\_protocol = string
protocol\_version = optional(string)
round\_robin = optional(bool, true)
host\_headers = optional(list(string))
http\_headers = optional(map(string))
http\_request\_method = optional(list(string))
path\_pattern = optional(list(string))
query\_strings = optional(map(string))
source\_ip = optional(list(string))
}))
}))
| n/a | yes | | [security\_groups](#input\_security\_groups) | A list of security group IDs to use with a Load Balancer.

If security groups are created with a [VPC module](../vpc) you can use output from that module like this:
security\_groups              = [module.vpc.security\_group\_ids["load\_balancer\_security\_group"]]
For more information on the `load_balancer_security_group` key refer to the [VPC module documentation](../vpc). | `list(string)` | n/a | yes | | [subnets](#input\_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 attribute
`id` identifying AWS subnet.

Examples:

You can define the values directly:
subnets = {
"us-east-1a" = { id = "snet-123007" }
"us-east-1b" = { id = "snet-123008" }
}
You can also use output from the `subnet_sets` module:
subnets        = { for k, v in module.subnet\_sets["untrust"].subnets : k => { id = v.id } }
|
map(object({
id = string
}))
| n/a | yes | | [tags](#input\_tags) | Map of AWS tags to apply to all the created resources. | `map(string)` | `{}` | no | diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/asg.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/asg.md index 6f836eb9c..ea1db5d82 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/asg.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/asg.md @@ -81,6 +81,9 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [airs\_deployment](#input\_airs\_deployment) | Deployment type VM-Series (False) or AI Runtime Security (True) | `bool` | `false` | no | +| [airs\_instance\_type](#input\_airs\_instance\_type) | EC2 instance type. | `string` | `"c6in.xlarge"` | no | +| [airs\_product\_code](#input\_airs\_product\_code) | Product code corresponding to a chosen AIRS license type model - by default - BYOL.
To check the available license type models and their codes, please refer to the | `string` | `"b261y39exndwe1ltro1tqpeog"` | no | | [asg\_name](#input\_asg\_name) | Name of the autoscaling group to create | `string` | `"asg"` | no | | [bootstrap\_options](#input\_bootstrap\_options) | Bootstrap options to put into userdata | `any` | `{}` | no | | [delete\_timeout](#input\_delete\_timeout) | Timeout needed to correctly drain autoscaling group while deleting ASG.

By default in AWS timeout is set to 10 minutes, which is too low and causes issue:
Error: waiting for Auto Scaling Group (example-asg) drain: timeout while waiting for state to become '0' (last state: '1', timeout: 10m0s) | `string` | `"20m"` | no | @@ -88,23 +91,23 @@ No modules. | [delicense\_ssm\_param\_name](#input\_delicense\_ssm\_param\_name) | Secure string in Parameter Store with value in below format:
{"username":"ACCOUNT","password":"PASSWORD","panorama1":"IP\_ADDRESS1","panorama2":"IP\_ADDRESS2","license\_manager":"LICENSE\_MANAGER\_NAME"}"
the format can either be the plain name in case you store it without hierarchy or with a "/" in case you store in in a hierarchy | `any` | `null` | no | | [desired\_capacity](#input\_desired\_capacity) | Number of Amazon EC2 instances that should be running in the group. | `number` | `2` | no | | [ebs\_kms\_id](#input\_ebs\_kms\_id) | Alias for AWS KMS used for EBS encryption in VM-Series | `string` | `"alias/aws/ebs"` | no | -| [enabled_metrics](#input_enabled_metrics) | List of Auto Scaling group metrics to collect. Set to an empty list to disable metrics collection. | `list(string)` |
[
"GroupMinSize",
"GroupMaxSize",
"GroupDesiredCapacity",
"GroupInServiceInstances",
"GroupPendingInstances",
"GroupStandbyInstances",
"GroupTerminatingInstances",
"GroupTotalInstances",
"WarmPoolDesiredCapacity",
"WarmPoolWarmedCapacity",
"WarmPoolPendingCapacity",
"WarmPoolTerminatingCapacity",
"WarmPoolTotalCapacity",
"GroupAndWarmPoolDesiredCapacity",
"GroupAndWarmPoolTotalCapacity",
]
| no | +| [enabled\_metrics](#input\_enabled\_metrics) | List of Auto Scaling group metrics to collect. Set to an empty list to disable metrics collection. | `list(string)` |
[
"GroupMinSize",
"GroupMaxSize",
"GroupDesiredCapacity",
"GroupInServiceInstances",
"GroupPendingInstances",
"GroupStandbyInstances",
"GroupTerminatingInstances",
"GroupTotalInstances",
"WarmPoolDesiredCapacity",
"WarmPoolWarmedCapacity",
"WarmPoolPendingCapacity",
"WarmPoolTerminatingCapacity",
"WarmPoolTotalCapacity",
"GroupAndWarmPoolDesiredCapacity",
"GroupAndWarmPoolTotalCapacity"
]
| no | | [fw\_license\_type](#input\_fw\_license\_type) | Select License type (byol/payg1/payg2) | `string` | `"byol"` | no | | [global\_tags](#input\_global\_tags) | Map of AWS tags to apply to all the created resources. | `map(any)` | n/a | yes | | [health\_check](#input\_health\_check) | Controls how health checking is done. |
object({
grace\_period = number
type = string
})
|
{
"grace\_period": 300,
"type": "EC2"
}
| no | | [include\_deprecated\_ami](#input\_include\_deprecated\_ami) | In certain scenarios, customers may deploy a VM-Series instance through the marketplace,
only to later discover that the ami has been deprecated, resulting in pipeline failures.
Setting the specified parameter to `true` will enable the continued use of deprecated AMIs,
mitigating this issue. | `bool` | `false` | no | | [instance\_refresh](#input\_instance\_refresh) | If this variable is configured (not null), then start an Instance Refresh when Auto Scaling Group is updated.

Instance refresh is defined by attributes:
- `strategy` - Strategy to use for instance refresh. The only allowed value is Rolling
- `preferences` - Override default parameters for Instance Refresh:
- `checkpoint_delay` - Number of seconds to wait after a checkpoint. Defaults to 3600.
- `checkpoint_percentages` - List of percentages for each checkpoint. Values must be unique and in ascending order.
To replace all instances, the final number must be 100.
- `instance_warmup` - Number of seconds until a newly launched instance is configured and ready to use.
Default behavior is to use the Auto Scaling Group's health check grace period.
- `min_healthy_percentage` - Amount of capacity in the Auto Scaling group that must remain healthy during an instance refresh
to allow the operation to continue, as a percentage of the desired capacity of the Auto Scaling group.
Defaults to 90.
- `skip_matching` - Replace instances that already have your desired configuration. Defaults to false.
- `auto_rollback` - Automatically rollback if instance refresh fails. Defaults to false.
This option may only be set to true when specifying a launch\_template or mixed\_instances\_policy.
- `scale_in_protected_instances` - Behavior when encountering instances protected from scale in are found.
Available behaviors are Refresh, Ignore, and Wait. Default is Ignore.
- `standby_instances` - Behavior when encountering instances in the Standby state in are found.
Available behaviors are Terminate, Ignore, and Wait. Default is Ignore.
- `trigger` - Set of additional property names that will trigger an Instance Refresh.
A refresh will always be triggered by a change in any of launch\_configuration, launch\_template, or mixed\_instances\_policy. |
object({
strategy = string
preferences = object({
checkpoint\_delay = number
checkpoint\_percentages = list(number)
instance\_warmup = number
min\_healthy\_percentage = number
skip\_matching = bool
auto\_rollback = bool
scale\_in\_protected\_instances = string
standby\_instances = string
})
triggers = list(string)
})
| `null` | no | | [instance\_type](#input\_instance\_type) | EC2 instance type. | `string` | `"m5.xlarge"` | no | -| [interfaces](#input\_interfaces) | Map of the network interface specifications.
If "mgmt-interface-swap" bootstrap option is enabled, ensure dataplane interface `device_index` is set to 0 and the firewall management interface `device_index` is set to 1.
Available options:
- `device_index` = (Required\|int) Determines order in which interfaces are attached to the instance. Interface with `0` is attached at boot time.
- `subnet_id` = (Required\|string) Subnet ID to create the ENI in.
- `name` = (Optional\|string) Name tag for the ENI. Defaults to instance name suffixed by map's key.
- `description` = (Optional\|string) A descriptive name for the ENI.
- `create_public_ip` = (Optional\|bool) Whether to create a public IP for the ENI. Defaults to false.
- `eip_allocation_id` = (Optional\|string) Associate an existing EIP to the ENI.
- `private_ips` = (Optional\|list) List of private IPs to assign to the ENI. If not set, dynamic allocation is used.
- `public_ipv4_pool` = (Optional\|string) EC2 IPv4 address pool identifier.
- `source_dest_check` = (Optional\|bool) Whether to enable source destination checking for the ENI. Defaults to false.
- `security_group_ids` = (Optional\|list) A list of Security Group IDs to assign to this interface. Defaults to null.

Example:
interfaces = {
mgmt = {
device\_index = 0
subnet\_id = aws\_subnet.mgmt.id
name = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
security\_group\_ids = ["sg-123456"]
},
public = {
device\_index = 1
subnet\_id = aws\_subnet.public.id
name = "public"
create\_public\_ip = true
},
private = {
device\_index = 2
subnet\_id = aws\_subnet.private.id
name = "private"
},
]
| `map(any)` | n/a | yes | +| [interfaces](#input\_interfaces) | Map of the network interface specifications.
If "mgmt-interface-swap" bootstrap option is enabled, ensure dataplane interface `device_index` is set to 0 and the firewall management interface `device_index` is set to 1.
Available options:
- `device_index` = (Required\|int) Determines order in which interfaces are attached to the instance. Interface with `0` is attached at boot time.
- `subnet_id` = (Required\|string) Subnet ID to create the ENI in.
- `name` = (Optional\|string) Name tag for the ENI. Defaults to instance name suffixed by map's key.
- `description` = (Optional\|string) A descriptive name for the ENI.
- `create_public_ip` = (Optional\|bool) Whether to create a public IP for the ENI. Defaults to false.
- `eip_allocation_id` = (Optional\|string) Associate an existing EIP to the ENI.
- `private_ips` = (Optional\|list) List of private IPs to assign to the ENI. If not set, dynamic allocation is used.
- `public_ipv4_pool` = (Optional\|string) EC2 IPv4 address pool identifier.
- `source_dest_check` = (Optional\|bool) Whether to enable source destination checking for the ENI. Defaults to false.
- `security_group_ids` = (Optional\|list) A list of Security Group IDs to assign to this interface. Defaults to null.

Example:
interfaces = {
mgmt = {
device\_index = 0
subnet\_id = aws\_subnet.mgmt.id
name = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
security\_group\_ids = ["sg-123456"]
},
public = {
device\_index = 1
subnet\_id = aws\_subnet.public.id
name = "public"
create\_public\_ip = true
},
private = {
device\_index = 2
subnet\_id = aws\_subnet.private.id
name = "private"
},
]
|
map(object({
device\_index = number
subnet\_id = map(string)
name = optional(string)
description = optional(string)
create\_public\_ip = optional(bool, false)
eip\_allocation\_id = optional(string)
private\_ips = optional(list(string))
ipv6\_address\_count = optional(number, null)
public\_ipv4\_pool = optional(string)
source\_dest\_check = optional(bool, false)
security\_group\_ids = optional(list(string), null)
}))
| n/a | yes | | [ip\_target\_groups](#input\_ip\_target\_groups) | Target groups (type IP) for load balancers, which are used by Lamda to register VM-Series IP of untrust interface |
list(object({
arn = string
port = string
}))
| `[]` | no | -| [lambda\_execute\_pip\_install\_once](#input\_lambda\_execute\_pip\_install\_once) | Flag used in local-exec command installing Python packages required by Lambda.

If set to true, local-exec is executed only once, when all resources are created.
If you need to have idempotent behaviour for terraform apply every time and you have downloaded
all required Python packages, set it to true.

If set to false, every time it's checked if files for package pan\_os\_python are downloaded.
If not, it causes execution of local-exec command in two consecutive calls of terraform apply:
- first time value of installed-pan-os-python is changed from true (or empty) to false
- second time value of installed-pan-os-python is changed from false to true
In summary while executing code from scratch, two consecutive calls of terraform apply are not idempotent.
The third execution of terraform apply show no changes.
While using modules in CI/CD pipelines, when agents are selected randomly, set this value to false
in order to check every time, if pan\_os\_python package is downloaded. sdfdsf sdfvars | `bool` | `false` | no | +| [lambda\_execute\_pip\_install\_once](#input\_lambda\_execute\_pip\_install\_once) | Flag used in local-exec command installing Python packages required by Lambda.

If set to true, local-exec is executed only once, when all resources are created.
If you need to have idempotent behaviour for terraform apply every time and you have downloaded
all required Python packages, set it to true.

If set to false, every time it's checked if files for package pan\_os\_python are downloaded.
If not, it causes execution of local-exec command in two consecutive calls of terraform apply:
- first time value of installed-pan-os-python is changed from true (or empty) to false
- second time value of installed-pan-os-python is changed from false to true
In summary while executing code from scratch, two consecutive calls of terraform apply are not idempotent.
The third execution of terraform apply show no changes.
While using modules in CI/CD pipelines, when agents are selected randomly, set this value to false
in order to check every time, if pan\_os\_python package is downloaded. | `bool` | `false` | no | | [lambda\_timeout](#input\_lambda\_timeout) | Amount of time Lambda Function has to run in seconds. | `number` | `30` | no | | [launch\_template\_update\_default\_version](#input\_launch\_template\_update\_default\_version) | Whether to update launch template default version each update.

If set to true, every time when e.g. bootstrap options are changed, new version is created and default version is updated.
If set to false, every time when e.g. bootstrap options are changed, new version is created, but default version is not changed. | `bool` | `true` | no | | [launch\_template\_version](#input\_launch\_template\_version) | Launch template version to use to launch instances | `string` | `"$Latest"` | no | | [lifecycle\_hook\_timeout](#input\_lifecycle\_hook\_timeout) | How long should we wait for lambda to finish | `number` | `300` | no | | [max\_size](#input\_max\_size) | Maximum size of the Auto Scaling Group. | `number` | `2` | no | +| [metrics\_granularity](#input\_metrics\_granularity) | Granularity for Auto Scaling group metrics. | `string` | `"1Minute"` | no | | [min\_size](#input\_min\_size) | Minimum size of the Auto Scaling Group. | `number` | `1` | no | -| [metrics_granularity](#input_metrics_granularity) | Granularity for Auto Scaling group metrics. | `string` | `"1Minute"` | no | | [name\_prefix](#input\_name\_prefix) | All resource names will be prepended with this string | `string` | n/a | yes | | [region](#input\_region) | AWS region | `string` | n/a | yes | | [reserved\_concurrent\_executions](#input\_reserved\_concurrent\_executions) | Amount of reserved concurrent execussions for lambda function. | `number` | `100` | no | @@ -124,7 +127,7 @@ No modules. | [vmseries\_ami\_id](#input\_vmseries\_ami\_id) | The AMI from which to launch the instance. Takes precedence over fw\_version and fw\_license\_type | `string` | `null` | no | | [vmseries\_iam\_instance\_profile](#input\_vmseries\_iam\_instance\_profile) | IAM instance profile used in launch template | `string` | `""` | no | | [vmseries\_product\_code](#input\_vmseries\_product\_code) | Product code corresponding to a chosen VM-Series license type model - by default - BYOL.
To check the available license type models and their codes, please refer to the
[VM-Series documentation](https://docs.paloaltonetworks.com/vm-series/10-0/vm-series-deployment/set-up-the-vm-series-firewall-on-aws/deploy-the-vm-series-firewall-on-aws/obtain-the-ami/get-amazon-machine-image-ids.html) | `string` | `"6njl1pau431dv1qxipg63mvah"` | no | -| [vmseries\_version](#input\_vmseries\_version) | Select which FW version to deploy | `string` | `"10.2.9-h1"` | no | +| [vmseries\_version](#input\_vmseries\_version) | VM-Series Firewall/AIRS version to deploy.
To list all available VM-Series versions, run the command provided below.
Please have in mind that the `product-code` may need to be updated - check the `vmseries_product_code` variable for more information.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=6njl1pau431dv1qxipg63mvah" "Name=name,Values=PA-VM-AWS*" --output json --query "Images[].Description" \| grep -o 'PA-VM-AWS-.\*' \| sort
To list all available AIRS versions, run the command provided below.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=b261y39exndwe1ltro1tqpeog" "Name=name,Values=PA-AI-Runtime-Security-AWS-\*" --output json --query "Images[].Name" \| grep -o 'PA-AI-Runtime-Security-AWS-.*' \| sort
| `string` | `"11.1.4-h7"` | no | ### Outputs diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/bootstrap.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/bootstrap.md index b8abc37de..28e8f57a3 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/bootstrap.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/bootstrap.md @@ -134,7 +134,7 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [bootstrap\_directories](#input\_bootstrap\_directories) | List of subdirectories to be created inside the bucket (whether or not they exist locally inside the `source_root_directory`). A hardcoded pan-os requirement. | `list(string)` |
[
"config/",
"content/",
"software/",
"license/",
"plugins/"
]
| no | -| [bootstrap\_options](#input\_bootstrap\_options) | Object define bootstrap options used in the init-cfg.txt file.

There are available bootstrap parameters:
- `hostname` - (`string`, optional) The hostname of the VM-series instance.
- `panorama-server` - (`string`, optional) The FQDN or IP address of the primary Panorama server.
- `panorama-server-2` - (`string`, optional) The FQDN or IP address of the secondary Panorama server.
- `tplname` - (`string`, optional) The Panorama template stack name.
- `dgname` - (`string`, optional) The Panorama device group name.
- `cgname` - (`string`, optional) The Panorama collector group name.
- `dns-primary` - (`string`, optional) The IP address of the primary DNS server.
- `dns-secondary` - (`string`, optional) The IP address of the secondary DNS server.
- `auth-key` - (`string`, optional) VM-Series authentication key generated via plugin sw\_fw\_license.
- `vm-auth-key` - (`string`, optional) VM-Series authentication key generated on Panorama.
- `op-command-modes` - (`string`, optional) Set jumbo-frame and/or mgmt-interface-swap.
- `plugin-op-commands` - (`string`, optional) Set plugin-op-commands.
- `dhcp-send-hostname` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall sends its hostname to the DHCP server.
- `dhcp-send-client-id` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall sends its client ID to the DHCP server.
- `dhcp-accept-server-hostname` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall accepts its hostname from the DHCP server.
- `dhcp-accept-server-domain` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall accepts its DNS server from the DHCP server. | `any` |
{
"dhcp-accept-server-domain": "yes",
"dhcp-accept-server-hostname": "yes",
"dhcp-send-client-id": "yes",
"dhcp-send-hostname": "yes"
}
| no | +| [bootstrap\_options](#input\_bootstrap\_options) | Object define bootstrap options used in the init-cfg.txt file.

There are available bootstrap parameters:
- `hostname` - (`string`, optional) The hostname of the VM-series instance.
- `mgmt-interface-swap` - (`string`, optional) Allows to swap the management interface with the dataplane interface eth1/1.
- `panorama-server` - (`string`, optional) The FQDN or IP address of the primary Panorama server.
- `panorama-server-2` - (`string`, optional) The FQDN or IP address of the secondary Panorama server.
- `tplname` - (`string`, optional) The Panorama template stack name.
- `dgname` - (`string`, optional) The Panorama device group name.
- `cgname` - (`string`, optional) The Panorama collector group name.
- `dns-primary` - (`string`, optional) The IP address of the primary DNS server.
- `dns-secondary` - (`string`, optional) The IP address of the secondary DNS server.
- `auth-key` - (`string`, optional) VM-Series authentication key generated via plugin sw\_fw\_license.
- `vm-auth-key` - (`string`, optional) VM-Series authentication key generated on Panorama.
- `op-command-modes` - (`string`, optional) Set jumbo-frame and/or mgmt-interface-swap.
- `plugin-op-commands` - (`string`, optional) Set plugin-op-commands.
- `dhcp-send-hostname` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall sends its hostname to the DHCP server.
- `dhcp-send-client-id` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall sends its client ID to the DHCP server.
- `dhcp-accept-server-hostname` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall accepts its hostname from the DHCP server.
- `dhcp-accept-server-domain` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall accepts its DNS server from the DHCP server.
- `authcodes` - (`string`, optional) The authcode use to register the VM-Series firewall.
- `vm-series-auto-registration-pin-id` - (`string`, optional) The VM-Series registration PIN ID for installing the device certificate on the VM-Series firewall.
- `vm-series-auto-registration-pin-value` - (`string`, optional) The VM-Series registration PIN Value for installing the device certificate on the VM-Series firewall. |
object({
hostname = optional(string)
mgmt-interface-swap = optional(string)
panorama-server = optional(string)
panorama-server-2 = optional(string)
tplname = optional(string)
dgname = optional(string)
cgname = optional(string)
dns-primary = optional(string)
dns-secondary = optional(string)
auth-key = optional(string)
vm-auth-key = optional(string)
op-command-modes = optional(string)
plugin-op-commands = optional(string)
dhcp-send-hostname = optional(string)
dhcp-send-client-id = optional(string)
dhcp-accept-server-hostname = optional(string)
dhcp-accept-server-domain = optional(string)
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})
| n/a | yes | | [bucket\_name](#input\_bucket\_name) | Name of a bucket to reuse or create (depending on `create_bucket` value). In the latter case - if empty, the name will be auto-generated. | `string` | `""` | no | | [create\_bucket](#input\_create\_bucket) | If true, a new bucket will be created. When false, name of existing bucket to use has to be provided in `bucket_name` variable. | `bool` | `true` | no | | [create\_iam\_role\_policy](#input\_create\_iam\_role\_policy) | If true, a new IAM role with policy will be created. When false, name of existing IAM role to use has to be provided in `iam_role_name` variable. | `bool` | `true` | no | diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/cloudngfw.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/cloudngfw.md index 871320652..bb94ae62f 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/cloudngfw.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/cloudngfw.md @@ -37,14 +37,14 @@ For example usage, please refer to the [examples](https://github.com/PaloAltoNet |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.0, < 2.0.0 | | [aws](#requirement\_aws) | ~> 5.17 | -| [cloudngfwaws](#requirement\_cloudngfwaws) | 2.0.6 | +| [cloudngfwaws](#requirement\_cloudngfwaws) | 2.0.20 | ### Providers | Name | Version | |------|---------| | [aws](#provider\_aws) | ~> 5.17 | -| [cloudngfwaws](#provider\_cloudngfwaws) | 2.0.6 | +| [cloudngfwaws](#provider\_cloudngfwaws) | 2.0.20 | ### Modules @@ -56,11 +56,11 @@ No modules. |------|------| | [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | | [aws_cloudwatch_log_stream.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_stream) | resource | -| [cloudngfwaws_commit_rulestack.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.6/docs/resources/commit_rulestack) | resource | -| [cloudngfwaws_ngfw.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.6/docs/resources/ngfw) | resource | -| [cloudngfwaws_ngfw_log_profile.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.6/docs/resources/ngfw_log_profile) | resource | -| [cloudngfwaws_rulestack.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.6/docs/resources/rulestack) | resource | -| [cloudngfwaws_security_rule.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.6/docs/resources/security_rule) | resource | +| [cloudngfwaws_commit_rulestack.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.20/docs/resources/commit_rulestack) | resource | +| [cloudngfwaws_ngfw.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.20/docs/resources/ngfw) | resource | +| [cloudngfwaws_ngfw_log_profile.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.20/docs/resources/ngfw_log_profile) | resource | +| [cloudngfwaws_rulestack.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.20/docs/resources/rulestack) | resource | +| [cloudngfwaws_security_rule.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.20/docs/resources/security_rule) | resource | | [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | ### Inputs @@ -70,13 +70,13 @@ No modules. | [description](#input\_description) | Cloud NGFW description. | `string` | `"CloudNGFW"` | no | | [description\_rule](#input\_description\_rule) | The rulestack description. | `string` | `"CloudNGFW rulestack"` | no | | [endpoint\_mode](#input\_endpoint\_mode) | The endpoint mode indicate the creation method of endpoint for target VPC. Customer Managed required to create endpoint manually. | `string` | `"CustomerManaged"` | no | -| [log\_profiles](#input\_log\_profiles) | The CloudWatch logs group name should correspond with the assumed role generated in cfn.
- `create_cw` = (Required\|string) Whether to create AWS CloudWatch log group.
- `name` = (Required\|string) The CW log group should correspond with cfn cross zone role.
- `destination_type` = (Required\|string) Only supported type is "CloudWatchLogs".
- `log_type` = (Required\|string) The firewall log type.
Example:
log\_profiles = {
dest\_1 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "THREAT"
}
dest\_2 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "TRAFFIC"
}
dest\_3 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "DECRYPTION"
}
}
|
map(object({
create\_cw = bool
name = string
destination\_type = string
log\_type = string
}
))
| `{}` | no | +| [log\_profiles](#input\_log\_profiles) | The CloudWatch logs group name should correspond with the assumed role generated in cfn.
- `create_cw` = (Optional\|string) Whether to create AWS CloudWatch log group.
- `name` = (Required\|string) The CW log group should correspond with cfn cross zone role.
- `destination_type` = (Required\|string) Only supported type is "CloudWatchLogs".
- `log_type` = (Required\|string) The firewall log type.
Example:
log\_profiles = {
dest\_1 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "THREAT"
}
dest\_2 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "TRAFFIC"
}
dest\_3 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "DECRYPTION"
}
}
|
map(object({
create\_cw = optional(bool, false)
name = string
destination\_type = string
log\_type = string
}
))
| `{}` | no | | [name](#input\_name) | Name of the Cloud NGFW instance. | `string` | n/a | yes | | [profile\_config](#input\_profile\_config) | The rulestack profile config. | `map(any)` | `{}` | no | | [retention\_in\_days](#input\_retention\_in\_days) | CloudWatch log groups retains logs. | `number` | `365` | no | | [rulestack\_name](#input\_rulestack\_name) | The rulestack name. | `string` | n/a | yes | | [rulestack\_scope](#input\_rulestack\_scope) | The rulestack scope. A local rulestack will require that you've retrieved a LRA JWT. A global rulestack will require that you've retrieved a GRA JWT | `string` | `"Local"` | no | -| [security\_rules](#input\_security\_rules) | Example:
security\_rules = {
rule\_1 = {
rule\_list = "LocalRule"
priority = 3
name = "tf-security-rule"
description = "Also configured by Terraform"
source\_cidrs = ["any"]
destination\_cidrs = ["0.0.0.0/0"]
negate\_destination = false
protocol = "application-default"
applications = ["any"]
category\_feeds = [""]
category\_url\_category\_names = [""]
action = "Allow"
logging = true
audit\_comment = "initial config"
}
}
|
map(object({
rule\_list = string
priority = number
name = string
description = string
source\_cidrs = set(string)
destination\_cidrs = set(string)
negate\_destination = bool
protocol = string
applications = set(string)
category\_feeds = set(string)
category\_url\_category\_names = set(string)
action = string
logging = bool
audit\_comment = string
}))
| `{}` | no | +| [security\_rules](#input\_security\_rules) | Example:
security\_rules = {
rule\_1 = {
rule\_list = "LocalRule"
priority = 3
name = "tf-security-rule"
description = "Also configured by Terraform"
source\_cidrs = ["any"]
destination\_cidrs = ["0.0.0.0/0"]
negate\_destination = false
protocol = "application-default"
applications = ["any"]
category\_feeds = [""]
category\_url\_category\_names = [""]
action = "Allow"
logging = true
audit\_comment = "initial config"
}
}
|
map(object({
rule\_list = string
priority = number
name = string
description = optional(string)
source\_cidrs = set(string)
destination\_cidrs = set(string)
negate\_destination = optional(bool, false)
protocol = optional(string, "application-default")
applications = optional(set(string), ["any"])
category\_feeds = optional(set(string))
category\_url\_category\_names = optional(set(string))
action = string
logging = bool
audit\_comment = optional(string)
}))
| `{}` | no | | [subnets](#input\_subnets) | Map of Subnets where to create the NAT Gateways. Each map's key is the availability zone name and each map's object has an attribute `id` identifying AWS Subnet. Importantly, the traffic returning from the NAT Gateway uses the Subnet's route table.
The keys of this input map are used for the output map `endpoints`.
Example for users of module `subnet_set`:
subnets = module.subnet\_set.subnets
Example:
subnets = {
"us-east-1a" = { id = "snet-123007" }
"us-east-1b" = { id = "snet-123008" }
}
|
map(object({
id = string
tags = map(string)
}))
| n/a | yes | | [tags](#input\_tags) | AWS Tags for the VPC Endpoints. | `map(string)` | `{}` | no | | [vpc\_id](#input\_vpc\_id) | ID of the security VPC the Load Balancer should be created in. | `string` | n/a | yes | diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/gwlb_endpoint_set.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/gwlb_endpoint_set.md index ca4e08b0d..79a26ec6a 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/gwlb_endpoint_set.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/gwlb_endpoint_set.md @@ -63,7 +63,7 @@ No modules. | [delay](#input\_delay) | If Service Account name belongs to different AWS account It might delay endpoint status changes. It leads to routing issue. The variable should be applied for CloudNGFW. Number of seconds. | `number` | `0` | no | | [gwlb\_service\_name](#input\_gwlb\_service\_name) | The name of the VPC Endpoint Service to connect to, which may reside in a different VPC. Usually an output `module.gwlb.endpoint_service.service_name`. Example: "com.amazonaws.vpce.eu-west-3.vpce-svc-0df5336455053eb2b". | `string` | n/a | yes | | [gwlb\_service\_type](#input\_gwlb\_service\_type) | The type of the Endpoint to create for `gwlb_service_name`. | `string` | `"GatewayLoadBalancer"` | no | -| [name](#input\_name) | Name of the VPC Endpoint Set, for example: "my-gwlbe-". Each individual endpoint is named by appending an AZ letter, such as "my-set-a" and "my-set-b". These names can be overridden using `custom_names`. | `string` | `"gwlbe-"` | no | +| [name](#input\_name) | Name of the VPC Endpoint Set, for example: "my-gwlbe-". Each individual endpoint is named by appending an AZ letter, such as "my-set-a" and "my-set-b". These names can be overriden using `custom_names`. | `string` | `"gwlbe-"` | no | | [subnets](#input\_subnets) | Map of Subnets where to create the Endpoints. Each map's key is the availability zone name and each map's object has an attribute
`id` identifying AWS Subnet. Importantly, the traffic returning from the Endpoint uses the Subnet's route table.
The keys of this input map are used for the output map `endpoints`.
Example for users of module `subnet_set`:
subnets = module.subnet\_set.subnets
Example:
subnets = {
"us-east-1a" = { id = "snet-123007" }
"us-east-1b" = { id = "snet-123008" }
}
|
map(object({
id = string
}))
| n/a | yes | | [tags](#input\_tags) | AWS Tags for the VPC Endpoints. | `map(string)` | `{}` | no | | [vpc\_id](#input\_vpc\_id) | AWS identifier of a VPC containing the Endpoint. | `string` | n/a | yes | @@ -74,4 +74,4 @@ No modules. |------|-------------| | [endpoints](#output\_endpoints) | Map of the created endpoints. The keys are the same as the keys of the input `subnets`. | | [next\_hop\_set](#output\_next\_hop\_set) | The Next Hop Set object, useful as an input to the `vpc_route` module. The intention would
be to route traffic from subnets to endpoints while preventing cross-AZ traffic (so
that a subnet in AZ-a only routes to an endpoint in AZ-a). Example:
next\_hop\_set = {
ids = {
"us-east-1a" = "gwlbe-0ddf598f93a8ea8ae"
"us-east-1b" = "gwlbe-0862c4b707b012111"
}
id = null
type = "vpc\_endpoint"
}
| - + \ No newline at end of file diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/nat_gateway_set.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/nat_gateway_set.md index db0ebba57..cb8d86a2f 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/nat_gateway_set.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/nat_gateway_set.md @@ -92,9 +92,9 @@ No modules. | [create\_nat\_gateway](#input\_create\_nat\_gateway) | If false, does not create a new NAT Gateway, but instead reads a pre-existing one. | `bool` | `true` | no | | [eip\_domain](#input\_eip\_domain) | Indicates if this EIP is for use in VPC | `string` | `"vpc"` | no | | [eip\_tags](#input\_eip\_tags) | n/a | `map(string)` | `{}` | no | -| [eips](#input\_eips) | Optional map of Elastic IP attributes. Each key is an Availability Zone name, for example "us-east-1b". Each entry has optional attributes `name`, `public_ip`, `id`.
These are mainly useful to select a pre-existing Elastic IP when create\_eip is false. Example:
eips = {
"us-east-1a" = { id = aws\_eip.a.id }
"us-east-1b" = { id = aws\_eip.b.id }
}
The `name` attribute can be used both for selecting the pre-existing Elastic IP, or for customizing a newly created Elastic IP:
eips = {
"us-east-1a" = { name = "Alice" }
"us-east-1b" = { name = "Bob" }
}
| `map` | `{}` | no | +| [eips](#input\_eips) | Optional map of Elastic IP attributes. Each key is an Availability Zone name, for example "us-east-1b". Each entry has optional attributes `name`, `public_ip`, `id`.
These are mainly useful to select a pre-existing Elastic IP when create\_eip is false. Example:
eips = {
"us-east-1a" = { id = aws\_eip.a.id }
"us-east-1b" = { id = aws\_eip.b.id }
}
The `name` attribute can be used both for selecting the pre-existing Elastic IP, or for customizing a newly created Elastic IP:
eips = {
"us-east-1a" = { name = "Alice" }
"us-east-1b" = { name = "Bob" }
}
|
map(object({
create\_eip = optional(bool, true)
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
}))
| `{}` | no | | [global\_tags](#input\_global\_tags) | n/a | `map(string)` | `{}` | no | -| [nat\_gateway\_names](#input\_nat\_gateway\_names) | A map, where each key is an Availability Zone name, for example "us-east-1b". Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
The name is kept in an AWS standard Name tag.
Example:
nat\_gateway\_names = {
"us-east-1a" = "example-natgwa"
"us-east-1b" = "example-natgwb"
}
| `map(string)` | `{}` | no | +| [nat\_gateway\_names](#input\_nat\_gateway\_names) | A map, where each key is an Availability Zone name, for example "us-east-1b". Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
The name is kept in an AWS standard Name tag.
Example:
nat\_gateway\_names = {
"us-east-1a" = "example-natgwa"
"us-east-1b" = "example-natgwb"
}
| `map(string)` | `{}` | no | | [nat\_gateway\_tags](#input\_nat\_gateway\_tags) | n/a | `map(string)` | `{}` | no | | [subnets](#input\_subnets) | Map of Subnets where to create the NAT Gateways. Each map's key is the availability zone name and each map's object has an attribute `id` identifying AWS Subnet. Importantly, the traffic returning from the NAT Gateway uses the Subnet's route table.
The keys of this input map are used for the output map `endpoints`.
Example for users of module `subnet_set`:
subnets = module.subnet\_set.subnets
Example:
subnets = {
"us-east-1a" = { id = "snet-123007" }
"us-east-1b" = { id = "snet-123008" }
}
|
map(object({
id = string
tags = map(string)
}))
| n/a | yes | diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/nlb.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/nlb.md index bbe9265df..457a0bec0 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/nlb.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/nlb.md @@ -74,7 +74,7 @@ No modules. | [access\_logs\_byob](#input\_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](#input\_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](#input\_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 | -| [balance\_rules](#input\_balance\_rules) | An object that contains the listener, target group, and health check configuration.
It consist of maps of applications like follows:
balance\_rules = {
"application\_name" = {
protocol = "communication protocol, since this is a NLB module accepted values are TCP or TLS"
port = "communication port"
target\_type = "type of the target that will be attached to a target group, no defaults here, has to be provided explicitly (regardless the defaults terraform could accept)"
target\_port = "for target types supporting port values, the port number on which the target accepts communication, defaults to the communication port value"
targets = "a map of targets, where key is the target name (used to create a name for the target attachment), value is the target ID (IP, resource ID, etc - the actual value depends on the target type)"
target\_az = "This parameter is not supported if the target type of the target group is instance or alb. If the target type is ip and the IP address is outside the VPC, this parameter is required."
health\_check\_port = "port used by the target group healthcheck, if ommited, `traffic-port` will be used"
threshold = "number of consecutive health checks before considering target healthy or unhealthy, defaults to 3"
interval = "time between each health check, between 5 and 300 seconds, defaults to 30s"
preserve\_client\_ip = "whether client IP preservation is enabled, by default disabled for protocols TCP and TLS, enabled for others"

certificate\_arn = "(TLS ONLY) this is the arn of a certificate"
alpn\_policy = "(TLS ONLY) ALPN policy name, for possible values check (terraform documentation)[https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb\_listener#alpn\_policy], defaults to `None`"
}
}
The `application_name` key is valid only for letters, numbers and a dash (`-`) - that's an AWS limitation.



`protocol` and `port` are used for `listener`, `target group` and `target group attachment`. Partially also for health checks (see below).



All listeners are always of forward action.



If you add FWs as targets, make sure you use `target_type = "ip"` and you provide the correct FW IPs in `target` map. IPs should be from the subnet set that the Load Balancer was created in. An example on how to feed this variable with data:
fw\_instance\_ips = { for k, v in var.vmseries : k => module.vmseries[k].interfaces["untrust"].private\_ip }
For format of `var.vmseries` check the (`vmseries` module)[../vmseries/README.md]. 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:
{
vm01 = "1.1.1.1"
vm02 = "2.2.2.2"
...
}


Healthchecks are by default of type TCP. Reason for that is the fact, that HTTP requests might flow through the FW to the actual application. So instead of checking the status of the FW we might check the status of the application.

You have an option to specify a health check port. This way you can set up a Management Profile with an Administrative Management Service limited only to NLBs private IPs and use a port for that service as the health check port. This way you make sure you separate the actual health check from the application rule's port.



EXAMPLE
balance\_rules = {
"HTTPS-APP" = {
protocol = "TCP"
port = "443"
health\_check\_port = "80"
threshold = 2
interval = 10
target\_port = 8443
target\_type = "ip"
targets = { for k, v in var.vmseries : k => module.vmseries[k].interfaces["untrust"].private\_ip }
target\_az = "all"
stickiness = true
preserve\_client\_ip = true
}
}
| `any` | n/a | yes | +| [balance\_rules](#input\_balance\_rules) | An object that contains the listener, target group, and health check configuration.
It consist of maps of applications like follows:
balance\_rules = {
"application\_name" = {
protocol = "communication protocol, since this is a NLB module accepted values are TCP or TLS"
port = "communication port"
target\_type = "type of the target that will be attached to a target group, no defaults here, has to be provided explicitly (regardless the defaults terraform could accept)"
target\_port = "for target types supporting port values, the port number on which the target accepts communication, defaults to the communication port value"
targets = "a map of targets, where key is the target name (used to create a name for the target attachment), value is the target ID (IP, resource ID, etc - the actual value depends on the target type)"
target\_az = "This parameter is not supported if the target type of the target group is instance or alb. If the target type is ip and the IP address is outside the VPC, this parameter is required."
health\_check\_port = "port used by the target group healthcheck, if ommited, `traffic-port` will be used"
threshold = "number of consecutive health checks before considering target healthy or unhealthy, defaults to 3"
interval = "time between each health check, between 5 and 300 seconds, defaults to 30s"
preserve\_client\_ip = "whether client IP preservation is enabled, by default disabled for protocols TCP and TLS, enabled for others"

certificate\_arn = "(TLS ONLY) this is the arn of a certificate"
alpn\_policy = "(TLS ONLY) ALPN policy name, for possible values check (terraform documentation)[https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb\_listener#alpn\_policy], defaults to `None`"
}
}
The `application_name` key is valid only for letters, numbers and a dash (`-`) - that's an AWS limitation.



`protocol` and `port` are used for `listener`, `target group` and `target group attachment`. Partially also for health checks (see below).



All listeners are always of forward action.



If you add FWs as targets, make sure you use `target_type = "ip"` and you provide the correct FW IPs in `target` map. IPs should be from the subnet set that the Load Balancer was created in. An example on how to feed this variable with data:
fw\_instance\_ips = { for k, v in var.vmseries : k => module.vmseries[k].interfaces["untrust"].private\_ip }
For format of `var.vmseries` check the (`vmseries` module)[../vmseries/README.md]. 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:
{
vm01 = "1.1.1.1"
vm02 = "2.2.2.2"
...
}


Healthchecks are by default of type TCP. Reason for that is the fact, that HTTP requests might flow through the FW to the actual application. So instead of checking the status of the FW we might check the status of the application.

You have an option to specify a health check port. This way you can set up a Management Profile with an Administrative Management Service limited only to NLBs private IPs and use a port for that service as the health check port. This way you make sure you separate the actual health check from the application rule's port.



EXAMPLE
balance\_rules = {
"HTTPS-APP" = {
protocol = "TCP"
port = "443"
health\_check\_port = "80"
threshold = 2
interval = 10
target\_port = 8443
target\_type = "ip"
targets = { for k, v in var.vmseries : k => module.vmseries[k].interfaces["untrust"].private\_ip }
target\_az = "all"
stickiness = true
preserve\_client\_ip = true
}
}
|
map(object({
protocol = string
port = string
health\_check\_port = optional(string, "traffic-port")
threshold = optional(number)
interval = optional(number)
target\_port = optional(string)
target\_type = string
targets = map(string)
target\_az = optional(string)
preserve\_client\_ip = optional(bool)
stickiness = optional(bool)
certificate\_arn = optional(string)
alpn\_policy = optional(string)
}))
| n/a | yes | | [configure\_access\_logs](#input\_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 | | [create\_dedicated\_eips](#input\_create\_dedicated\_eips) | If set to `true`, a set of EIPs will be created for each zone/subnet. Otherwise AWS will handle IP management. | `bool` | `false` | no | | [enable\_cross\_zone\_load\_balancing](#input\_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 | diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/panorama.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/panorama.md index 88c593683..ddf696f1d 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/panorama.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/panorama.md @@ -68,7 +68,7 @@ No modules. | [create\_public\_ip](#input\_create\_public\_ip) | If true, create an Elastic IP address for Panorama. | `bool` | `false` | no | | [ebs\_encrypted](#input\_ebs\_encrypted) | Whether to enable EBS encryption on root volume. | `bool` | `true` | no | | [ebs\_kms\_key\_alias](#input\_ebs\_kms\_key\_alias) | The alias for the customer managed KMS key to use for volume encryption.
If this is set to `null` the default master key that protects EBS volumes will be used | `string` | `"alias/aws/ebs"` | no | -| [ebs\_volumes](#input\_ebs\_volumes) | List of EBS volumes to create and attach to Panorama.
Available options:
- `name` (Optional) Name tag for the EBS volume. If not provided defaults to the value of `var.name`.
- `ebs_device_name` (Required) The EBS device name to expose to the instance (for example, /dev/sdh or xvdh).
See [Device Naming on Linux Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html#available-ec2-device-names) for more information.
- `ebs_size` (Optional) The size of the EBS volume in GiBs. Defaults to 2000 GiB.
- `force_detach` (Optional) Set to true if you want to force the volume to detach. Useful if previous attempts failed, but use this option only as a last resort, as this can result in data loss.
- `skip_destroy` (Optional) Set this to true if you do not wish to detach the volume from the instance to which it is attached at destroy time, and instead just remove the attachment from Terraform state.
This is useful when destroying an instance attached to third-party volumes.

Note: Terraform must be running with credentials which have the `GenerateDataKeyWithoutPlaintext` permission on the specified KMS key
as required by the [EBS KMS CMK volume provisioning process](https://docs.aws.amazon.com/kms/latest/developerguide/services-ebs.html#ebs-cmk) to prevent a volume from being created and almost immediately deleted.
If null, the default EBS encryption KMS key in the current region is used.

Example:
ebs\_volumes = [
{
name = "ebs-1"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
{
name = "ebs-2"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
{
name = "ebs-3"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
]
| `list(any)` | `[]` | no | +| [ebs\_volumes](#input\_ebs\_volumes) | List of EBS volumes to create and attach to Panorama.
Available options:
- `name` (Optional) Name tag for the EBS volume. If not provided defaults to the value of `var.name`.
- `ebs_device_name` (Required) The EBS device name to expose to the instance (for example, /dev/sdh or xvdh).
See [Device Naming on Linux Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html#available-ec2-device-names) for more information.
- `ebs_size` (Optional) The size of the EBS volume in GiBs. Defaults to 2000 GiB.
- `force_detach` (Optional) Set to true if you want to force the volume to detach. Useful if previous attempts failed, but use this option only as a last resort, as this can result in data loss.
- `skip_destroy` (Optional) Set this to true if you do not wish to detach the volume from the instance to which it is attached at destroy time, and instead just remove the attachment from Terraform state.
This is useful when destroying an instance attached to third-party volumes.

Note: Terraform must be running with credentials which have the `GenerateDataKeyWithoutPlaintext` permission on the specified KMS key
as required by the [EBS KMS CMK volume provisioning process](https://docs.aws.amazon.com/kms/latest/developerguide/services-ebs.html#ebs-cmk) to prevent a volume from being created and almost immediately deleted.
If null, the default EBS encryption KMS key in the current region is used.

Example:
ebs\_volumes = [
{
name = "ebs-1"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
{
name = "ebs-2"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
{
name = "ebs-3"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
]
|
list(object({
name = optional(string)
ebs\_device\_name = string
ebs\_size = optional(string, "2000")
force\_detach = optional(bool, false)
skip\_destroy = optional(bool, false)
}))
| `[]` | no | | [eip\_domain](#input\_eip\_domain) | Indicates if this EIP is for use in VPC | `string` | `"vpc"` | no | | [enable\_imdsv2](#input\_enable\_imdsv2) | Whether to enable IMDSv2 on the EC2 instance.
Support for this feature has been added in VM-Series Plugin [3.0.0](https://docs.paloaltonetworks.com/plugins/vm-series-and-panorama-plugins-release-notes/vm-series-plugin/vm-series-plugin-30/vm-series-plugin-300#id126d0957-95d7-4b29-9147-fff20027986e), which in turn requires PAN-OS version 10.2.0 at minimum. | `string` | `false` | no | | [enable\_monitoring](#input\_enable\_monitoring) | (Optional) If true, the launched EC2 instance will have detailed monitoring enabled. | `bool` | `false` | no | diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/subnet_set.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/subnet_set.md index 54c945d4a..8689271ac 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/subnet_set.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/subnet_set.md @@ -85,7 +85,7 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [cidrs](#input\_cidrs) | Map describing configuration of subnets and route tables to create and/or use in the set.
Keys are CIDR blocks, values can consist of following items:
- `create_subnet` - (Optional\|bool) When `true` (default), subnet is created, otherwise existing one is used.
- `create_route_table` - (Optional\|bool) When `true` a dedicated route table is created, unless existing subnet is used.
- `associate_route_table` - (Optional\|bool) Unless set to `false`, route table is associated with the subnet.
- `existing_route_table_id` - (Optional\|string) Id of an existing route table to associate with the subnet.
- `name` - (Optional\|string) Name (tag) of a subnet and, optionally a route table, to create or use. Defaults to set name appended with zone letter id.
- `route_table_name` - (Optional\|string) Name (tag) of a subnet and, optionally a route table, to create or use. Defaults to `name` value.
- `ipv6_cidr_block` - (Optional\|string) IPv6 CIDR block. The subnet size must use a /64 prefix length.
- `map_public_ip_on_launch` - (Optional\|bool) Specify true to indicate that instances launched into the subnet should be assigned a public IP address.
- `local_tags` - (Optional\|map) Map of tags to assign to created resources. | `map(any)` | n/a | yes | +| [cidrs](#input\_cidrs) | Map describing configuration of subnets and route tables to create and/or use in the set.
Keys are CIDR blocks, values can consist of following items:
- `create_subnet` - (Optional\|bool) When `true` (default), subnet is created, otherwise existing one is used.
- `create_route_table` - (Optional\|bool) When `true` a dedicated route table is created, unless existing subnet is used.
- `associate_route_table` - (Optional\|bool) Unless set to `false`, route table is associated with the subnet.
- `existing_route_table_id` - (Optional\|string) Id of an existing route table to associate with the subnet.
- `name` - (Optional\|string) Name (tag) of a subnet and, optionally a route table, to create or use. Defaults to set name appended with zone letter id.
- `route_table_name` - (Optional\|string) Name (tag) of a subnet and, optionally a route table, to create or use. Defaults to `name` value.
- `ipv6_cidr_block` - (Optional\|string) IPv6 CIDR block. The subnet size must use a /64 prefix length.
- `map_public_ip_on_launch` - (Optional\|bool) Specify true to indicate that instances launched into the subnet should be assigned a public IP address.
- `local_tags` - (Optional\|map) Map of tags to assign to created resources. |
map(object({
az = string
create\_subnet = optional(bool, true)
create\_route\_table = optional(bool, true)
associate\_route\_table = optional(bool, true)
existing\_route\_table\_id = optional(string)
name = optional(string)
route\_table\_name = optional(string)
ipv6\_cidr = optional(string)
map\_public\_ip\_on\_launch = optional(bool)
local\_tags = optional(map(string))
}))
| n/a | yes | | [create\_shared\_route\_table](#input\_create\_shared\_route\_table) | Boolean flag whether to create a shared route tables. | `bool` | `false` | no | | [global\_tags](#input\_global\_tags) | Optional map of arbitrary tags to apply to all the created resources. | `map(string)` | `{}` | no | | [has\_secondary\_cidrs](#input\_has\_secondary\_cidrs) | The input that depends on the secondary CIDR ranges of the VPC `vpc_id`. The actual value (true or false) is ignored, the input is used only to delay subnet creation until the secondary CIDR ranges are processed by Terraform. | `bool` | `true` | no | diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/vmseries.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/vmseries.md index 084deb5d1..d2144d279 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/vmseries.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/vmseries.md @@ -70,7 +70,6 @@ No modules. | [airs\_deployment](#input\_airs\_deployment) | Deployment type VM-Series (False) or AI Runtime Security (True) | `bool` | `false` | no | | [airs\_instance\_type](#input\_airs\_instance\_type) | EC2 instance type. | `string` | `"c6in.xlarge"` | no | | [airs\_product\_code](#input\_airs\_product\_code) | Product code corresponding to a chosen AIRS license type model - by default - BYOL.
To check the available license type models and their codes, please refer to the | `string` | `"b261y39exndwe1ltro1tqpeog"` | no | -| [airs\_version](#input\_airs\_version) | AI Runtime Security version to deploy.
To list all available AIRS versions, run the command provided below.
Please have in mind that the `product-code` may need to be updated - check the `vmseries_product_code` variable for more information.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=b261y39exndwe1ltro1tqpeog" "Name=name,Values=PA-AI-Runtime-Security-AWS*" --output json --query "Images[].Description" \| grep -o 'PA-AI-Runtime-Security-AWS-.*' \| sort
| `string` | `"11.2.5-h1"` | no | | [bootstrap\_options](#input\_bootstrap\_options) | VM-Series bootstrap options to provide using instance user data. Contents determine type of bootstap method to use.
If empty (the default), bootstrap process is not triggered at all.
For more information on available methods, please refer to VM-Series documentation for specific version.
For 10.0 docs are available [here](https://docs.paloaltonetworks.com/vm-series/10-0/vm-series-deployment/bootstrap-the-vm-series-firewall.html). | `string` | `""` | no | | [ebs\_encrypted](#input\_ebs\_encrypted) | Whether to enable EBS encryption on volumes. | `bool` | `true` | no | | [ebs\_kms\_key\_alias](#input\_ebs\_kms\_key\_alias) | The alias for the customer managed KMS key to use for volume encryption. Should be prepended with the word "alias" followed by a forward slash (alias/example-key-alias).
If `null` (the default), the default master key that protects EBS volumes will be used. | `string` | `"alias/aws/ebs"` | no | @@ -81,13 +80,13 @@ No modules. | [iam\_instance\_profile](#input\_iam\_instance\_profile) | IAM instance profile. | `string` | `null` | no | | [include\_deprecated\_ami](#input\_include\_deprecated\_ami) | In certain scenarios, customers may deploy a VM-Series instance through the marketplace,
only to later discover that the ami has been deprecated, resulting in pipeline failures.
Setting the specified parameter to `true` will enable the continued use of deprecated AMIs,
mitigating this issue. | `bool` | `false` | no | | [instance\_type](#input\_instance\_type) | EC2 instance type. | `string` | `"m5.xlarge"` | no | -| [interfaces](#input\_interfaces) | Map of the network interface specifications.
If "mgmt-interface-swap" bootstrap option is enabled, ensure dataplane interface `device_index` is set to 0 and the firewall management interface `device_index` is set to 1.
Available options:
- `device_index` = (Required\|int) Determines order in which interfaces are attached to the instance. Interface with `0` is attached at boot time.
- `subnet_id` = (Required\|string) Subnet ID to create the ENI in.
- `name` = (Optional\|string) Name tag for the ENI. Defaults to instance name suffixed by map's key.
- `description` = (Optional\|string) A descriptive name for the ENI.
- `create_public_ip` = (Optional\|bool) Whether to create a public IP for the ENI. Defaults to false.
- `eip_allocation_id` = (Optional\|string) Associate an existing EIP to the ENI.
- `private_ips` = (Optional\|list) List of private IPs to assign to the ENI. If not set, dynamic allocation is used.
- `ipv6_address_count` = (Optional\|number) Number of IPv6 addresses that will be assigned to the interface (use only when IPv6 enabled in the subnet). Defaults to null.
- `public_ipv4_pool` = (Optional\|string) EC2 IPv4 address pool identifier.
- `source_dest_check` = (Optional\|bool) Whether to enable source destination checking for the ENI. Defaults to false.
- `security_group_ids` = (Optional\|list) A list of Security Group IDs to assign to this interface. Defaults to null.

Example:
interfaces = {
mgmt = {
device\_index = 0
subnet\_id = aws\_subnet.mgmt.id
name = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
security\_group\_ids = ["sg-123456"]
},
public = {
device\_index = 1
subnet\_id = aws\_subnet.public.id
name = "public"
create\_public\_ip = true
},
private = {
device\_index = 2
subnet\_id = aws\_subnet.private.id
name = "private"
},
]
| `map(any)` | n/a | yes | +| [interfaces](#input\_interfaces) | Map of the network interface specifications.
If "mgmt-interface-swap" bootstrap option is enabled, ensure dataplane interface `device_index` is set to 0 and the firewall management interface `device_index` is set to 1.
Available options:
- `device_index` = (Required\|int) Determines order in which interfaces are attached to the instance. Interface with `0` is attached at boot time.
- `subnet_id` = (Required\|string) Subnet ID to create the ENI in.
- `name` = (Optional\|string) Name tag for the ENI. Defaults to instance name suffixed by map's key.
- `description` = (Optional\|string) A descriptive name for the ENI.
- `create_public_ip` = (Optional\|bool) Whether to create a public IP for the ENI. Defaults to false.
- `eip_allocation_id` = (Optional\|string) Associate an existing EIP to the ENI.
- `private_ips` = (Optional\|list) List of private IPs to assign to the ENI. If not set, dynamic allocation is used.
- `ipv6_address_count` = (Optional\|number) Number of IPv6 addresses that will be assigned to the interface (use only when IPv6 enabled in the subnet). Defaults to null.
- `public_ipv4_pool` = (Optional\|string) EC2 IPv4 address pool identifier.
- `source_dest_check` = (Optional\|bool) Whether to enable source destination checking for the ENI. Defaults to false.
- `security_group_ids` = (Optional\|list) A list of Security Group IDs to assign to this interface. Defaults to null.

Example:
interfaces = {
mgmt = {
device\_index = 0
subnet\_id = aws\_subnet.mgmt.id
name = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
security\_group\_ids = ["sg-123456"]
},
public = {
device\_index = 1
subnet\_id = aws\_subnet.public.id
name = "public"
create\_public\_ip = true
},
private = {
device\_index = 2
subnet\_id = aws\_subnet.private.id
name = "private"
},
]
|
map(object({
device\_index = number
subnet\_id = string
name = optional(string)
description = optional(string)
create\_public\_ip = optional(bool, false)
eip\_allocation\_id = optional(string)
private\_ips = optional(list(string))
ipv6\_address\_count = optional(number, null)
public\_ipv4\_pool = optional(string)
source\_dest\_check = optional(bool, false)
security\_group\_ids = optional(list(string), null)
}))
| n/a | yes | | [name](#input\_name) | Name of the VM-Series instance. | `string` | `null` | no | | [ssh\_key\_name](#input\_ssh\_key\_name) | Name of AWS keypair to associate with instances. | `string` | n/a | yes | | [tags](#input\_tags) | Map of additional tags to apply to all resources. | `map(any)` | `{}` | no | | [vmseries\_ami\_id](#input\_vmseries\_ami\_id) | Specific AMI ID to use for VM-Series instance.
If `null` (the default), `vmseries_version` and `vmseries_product_code` vars are used to determine a public image to use. | `string` | `null` | no | | [vmseries\_product\_code](#input\_vmseries\_product\_code) | Product code corresponding to a chosen VM-Series license type model - by default - BYOL.
To check the available license type models and their codes, please refer to the
[VM-Series documentation](https://docs.paloaltonetworks.com/vm-series/10-0/vm-series-deployment/set-up-the-vm-series-firewall-on-aws/deploy-the-vm-series-firewall-on-aws/obtain-the-ami/get-amazon-machine-image-ids.html) | `string` | `"6njl1pau431dv1qxipg63mvah"` | no | -| [vmseries\_version](#input\_vmseries\_version) | VM-Series Firewall version to deploy.
To list all available VM-Series versions, run the command provided below.
Please have in mind that the `product-code` may need to be updated - check the `vmseries_product_code` variable for more information.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=6njl1pau431dv1qxipg63mvah" "Name=name,Values=PA-VM-AWS*" --output json --query "Images[].Description" \| grep -o 'PA-VM-AWS-.*' \| sort
| `string` | `"10.2.9-h1"` | no | +| [vmseries\_version](#input\_vmseries\_version) | VM-Series Firewall/AIRS version to deploy.
To list all available VM-Series versions, run the command provided below.
Please have in mind that the `product-code` may need to be updated - check the `vmseries_product_code` variable for more information.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=6njl1pau431dv1qxipg63mvah" "Name=name,Values=PA-VM-AWS*" --output json --query "Images[].Description" \| grep -o 'PA-VM-AWS-.\*' \| sort
To list all available AIRS versions, run the command provided below.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=b261y39exndwe1ltro1tqpeog" "Name=name,Values=PA-AI-Runtime-Security-AWS-\*" --output json --query "Images[].Name" \| grep -o 'PA-AI-Runtime-Security-AWS-.*' \| sort
| `string` | `"11.1.4-h7"` | no | ### Outputs diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/vpc.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/vpc.md index 55f2ec2d7..49c07bf48 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/vpc.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/vpc.md @@ -100,7 +100,7 @@ No modules. | [enable\_dns\_support](#input\_enable\_dns\_support) | A boolean flag to enable/disable DNS support in the VPC. [Defaults true](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#enable_dns_support). | `bool` | `null` | no | | [global\_tags](#input\_global\_tags) | Optional map of arbitrary tags to apply to all the created resources. | `map(string)` | `{}` | no | | [instance\_tenancy](#input\_instance\_tenancy) | VPC level [instance tenancy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#instance_tenancy). | `string` | `null` | no | -| [nacls](#input\_nacls) | The `nacls` variable is a map of maps, where each map represents an AWS NACL.

Example:
nacls = {
trusted\_path\_monitoring = {
name = "trusted-path-monitoring"
rules = {
block\_outbound\_icmp = {
rule\_number = 110
egress = true
protocol = "icmp"
rule\_action = "deny"
cidr\_block = "10.100.1.0/24"
from\_port = null
to\_port = null
}
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
}
}
}
}
| `any` | `{}` | no | +| [nacls](#input\_nacls) | The `nacls` variable is a map of maps, where each map represents an AWS NACL.

Example:
nacls = {
trusted\_path\_monitoring = {
name = "trusted-path-monitoring"
rules = {
block\_outbound\_icmp = {
rule\_number = 110
egress = true
protocol = "icmp"
rule\_action = "deny"
cidr\_block = "10.100.1.0/24"
from\_port = null
to\_port = null
}
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
}
}
}
}
|
map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
}))
| `{}` | no | | [name](#input\_name) | Name of the VPC to create or use. | `string` | n/a | yes | | [name\_internet\_gateway](#input\_name\_internet\_gateway) | Name of the IGW to create or use. | `string` | `null` | no | | [name\_vpn\_gateway](#input\_name\_vpn\_gateway) | Name of the VPN gateway to create. | `string` | `null` | no | @@ -108,7 +108,7 @@ No modules. | [route\_table\_internet\_gateway](#input\_route\_table\_internet\_gateway) | Name of route table for the IGW. | `string` | `null` | no | | [route\_table\_vpn\_gateway](#input\_route\_table\_vpn\_gateway) | Name of the route table for VPN gateway. | `string` | `null` | no | | [secondary\_cidr\_blocks](#input\_secondary\_cidr\_blocks) | Secondary CIDR block to assign to a new VPC. | `list(string)` | `[]` | no | -| [security\_groups](#input\_security\_groups) | The `security_groups` variable is a map of maps, where each map represents an AWS Security Group.
The key of each entry acts as the Security Group name.
List of available attributes of each Security Group entry:
- `rules`: A list of objects representing a Security Group rule. The key of each entry acts as the name of the rule and
needs to be unique across all rules in the Security Group.
List of attributes available to define a Security Group rule:
- `description`: Security Group description.
- `type`: Specifies if rule will be evaluated on ingress (inbound) or egress (outbound) traffic.
- `cidr_blocks`: List of CIDR blocks - for ingress, determines the traffic that can reach your instance. For egress
Determines the traffic that can leave your instance, and where it can go.
- `ipv6_cidr_blocks`: List of IPv6 CIDR blocks - for ingress, determines the traffic that can reach your instance. For egress
Determines the traffic that can leave your instance, and where it can go. Defaults to null.
- `prefix_list_ids`: List of Prefix List IDs
- `self`: security group itself will be added as a source to the rule. Cannot be specified with cidr\_blocks, or security\_groups.
- `source_security_groups`: list of security group IDs to be used as a source to the rule. Cannot be specified with cidr\_blocks, or self.


Example:
security\_groups = {
vmseries-mgmt = {
name = "vmseries-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"]
}
all-outbound-ipv6 = {
description = "Permit All traffic outbound"
type = "egress", from\_port = "0", to\_port = "0", protocol = "-1"
cidr\_blocks = ["::/0"]
}
https-inbound-private = {
description = "Permit HTTPS for VM-Series Management"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
cidr\_blocks = ["10.0.0.0/8"]
}
https-inbound-eip = {
description = "Permit HTTPS for VM-Series Management from known public IPs"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
cidr\_blocks = ["100.100.100.100/32"]
}
ssh-inbound-eip = {
description = "Permit SSH for VM-Series Management from known public IPs"
type = "ingress", from\_port = "22", to\_port = "22", protocol = "tcp"
cidr\_blocks = ["100.100.100.100/32"]
}
https-inbound-self = {
description = "Permit HTTPS from instances with the same security group"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
self = true
}
https-inbound-security-groups = {
description = "Permit HTTPS traffic for the resources associated with the specified security group"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
source\_security\_groups = ["sg-1a2b3c4d5e6f7g8h9i"]
}
https-inbound-prefix-list = {
description = "Permit HTTPS for VM-Series Management for IPs in managed prefix list"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
prefix\_list\_ids = ["pl-1a2b3c4d5e6f7g8h9i"]
}
}
}
}
| `any` | `{}` | no | +| [security\_groups](#input\_security\_groups) | The `security_groups` variable is a map of maps, where each map represents an AWS Security Group.
The key of each entry acts as the Security Group name.
List of available attributes of each Security Group entry:
- `rules`: A map of objects representing a Security Group rule. The key of each entry
needs to be unique across all rules in the Security Group.
List of attributes available to define a Security Group rule:
- `description`: Security Group description.
- `type`: Specifies if rule will be evaluated on ingress (inbound) or egress (outbound) traffic.
- `cidr_blocks`: List of CIDR blocks - for ingress, determines the traffic that can reach your instance. For egress
Determines the traffic that can leave your instance, and where it can go.
- `ipv6_cidr_blocks`: List of IPv6 CIDR blocks - for ingress, determines the traffic that can reach your instance. For egress
Determines the traffic that can leave your instance, and where it can go. Defaults to null.
- `prefix_list_ids`: List of Prefix List IDs
- `self`: security group itself will be added as a source to the rule. Cannot be specified with cidr\_blocks, or security\_groups.
- `source_security_groups`: list of security group IDs to be used as a source to the rule. Cannot be specified with cidr\_blocks, or self.


Example:
security\_groups = {
vmseries-mgmt = {
name = "vmseries-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"]
}
all-outbound-ipv6 = {
description = "Permit All traffic outbound"
type = "egress", from\_port = "0", to\_port = "0", protocol = "-1"
cidr\_blocks = ["::/0"]
}
https-inbound-private = {
description = "Permit HTTPS for VM-Series Management"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
cidr\_blocks = ["10.0.0.0/8"]
}
https-inbound-eip = {
description = "Permit HTTPS for VM-Series Management from known public IPs"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
cidr\_blocks = ["100.100.100.100/32"]
}
ssh-inbound-eip = {
description = "Permit SSH for VM-Series Management from known public IPs"
type = "ingress", from\_port = "22", to\_port = "22", protocol = "tcp"
cidr\_blocks = ["100.100.100.100/32"]
}
https-inbound-self = {
description = "Permit HTTPS from instances with the same security group"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
self = true
}
https-inbound-security-groups = {
description = "Permit HTTPS traffic for the resources associated with the specified security group"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
source\_security\_groups = ["sg-1a2b3c4d5e6f7g8h9i"]
}
https-inbound-prefix-list = {
description = "Permit HTTPS for VM-Series Management for IPs in managed prefix list"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
prefix\_list\_ids = ["pl-1a2b3c4d5e6f7g8h9i"]
}
}
}
}
|
map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
}))
| `{}` | no | | [use\_internet\_gateway](#input\_use\_internet\_gateway) | If an existing VPC is provided and has IG attached, set to `true` to reuse it. | `bool` | `false` | no | | [vpc\_tags](#input\_vpc\_tags) | Optional map of arbitrary tags to apply to VPC resource. | `map` | `{}` | no | | [vpn\_gateway\_amazon\_side\_asn](#input\_vpn\_gateway\_amazon\_side\_asn) | ASN for the Amazon side of the gateway. | `string` | `null` | no | diff --git a/products/terraform/docs/swfw/aws/cloudngfw/modules/vpn.md b/products/terraform/docs/swfw/aws/cloudngfw/modules/vpn.md index efe8d5920..5ceee6240 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/modules/vpn.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/modules/vpn.md @@ -73,7 +73,7 @@ No modules. | [transit\_gateway\_associate\_route\_table\_id](#input\_transit\_gateway\_associate\_route\_table\_id) | TGW route table ID used to associate VPN attachments created by VPN connections | `string` | n/a | yes | | [transit\_gateway\_id](#input\_transit\_gateway\_id) | TGW's ID used by VPN connection | `string` | n/a | yes | | [transit\_gateway\_propagate\_route\_table\_id](#input\_transit\_gateway\_propagate\_route\_table\_id) | TGW route table ID into which VPN attachment will propagate routes received by BGP | `string` | n/a | yes | -| [vpn\_connection](#input\_vpn\_connection) | VPN connection defined by attributes:
- customer\_gateway\_id - (Required) The ID of the customer gateway.
- type - (Required) The type of VPN connection. The only type AWS supports at this time is "ipsec.1".
- transit\_gateway\_id - (Optional) The ID of the EC2 Transit Gateway.
- static\_routes\_only - (Optional, Default false) Whether the VPN connection uses static routes exclusively. Static routes must be used for devices that don't support BGP.
- enable\_acceleration - (Optional, Default false) Indicate whether to enable acceleration for the VPN connection. Supports only EC2 Transit Gateway.
- tags - (Optional) Tags to apply to the connection. If configured with a provider default\_tags configuration block present, tags with matching keys will overwrite those defined at the provider-level.
- local\_ipv4\_network\_cidr - (Optional, Default 0.0.0.0/0) The IPv4 CIDR on the customer gateway (on-premises) side of the VPN connection.
- local\_ipv6\_network\_cidr - (Optional, Default ::/0) The IPv6 CIDR on the customer gateway (on-premises) side of the VPN connection.
- outside\_ip\_address\_type - (Optional, Default PublicIpv4) Indicates if a Public S2S VPN or Private S2S VPN over AWS Direct Connect. Valid values are PublicIpv4 \| PrivateIpv4
- remote\_ipv4\_network\_cidr - (Optional, Default 0.0.0.0/0) The IPv4 CIDR on the AWS side of the VPN connection.
- remote\_ipv6\_network\_cidr - (Optional, Default ::/0) The IPv6 CIDR on the customer gateway (on-premises) side of the VPN connection.
- transport\_transit\_gateway\_attachment\_id - (Required when outside\_ip\_address\_type is set to PrivateIpv4). The attachment ID of the Transit Gateway attachment to Direct Connect Gateway. The ID is obtained through a data source only.
- tunnel\_inside\_ip\_version - (Optional, Default ipv4) Indicate whether the VPN tunnels process IPv4 or IPv6 traffic. Valid values are ipv4 \| ipv6. ipv6 Supports only EC2 Transit Gateway.
- tunnel1\_inside\_cidr - (Optional) The CIDR block of the inside IP addresses for the first VPN tunnel. Valid value is a size /30 CIDR block from the 169.254.0.0/16 range.
- tunnel2\_inside\_cidr - (Optional) The CIDR block of the inside IP addresses for the second VPN tunnel. Valid value is a size /30 CIDR block from the 169.254.0.0/16 range.
- tunnel1\_inside\_ipv6\_cidr - (Optional) The range of inside IPv6 addresses for the first VPN tunnel. Supports only EC2 Transit Gateway. Valid value is a size /126 CIDR block from the local fd00::/8 range.
- tunnel2\_inside\_ipv6\_cidr - (Optional) The range of inside IPv6 addresses for the second VPN tunnel. Supports only EC2 Transit Gateway. Valid value is a size /126 CIDR block from the local fd00::/8 range.
- tunnel1\_preshared\_key - (Optional) The preshared key of the first VPN tunnel. The preshared key must be between 8 and 64 characters in length and cannot start with zero(0). Allowed characters are alphanumeric characters, periods(.) and underscores(\_).
- tunnel2\_preshared\_key - (Optional) The preshared key of the second VPN tunnel. The preshared key must be between 8 and 64 characters in length and cannot start with zero(0). Allowed characters are alphanumeric characters, periods(.) and underscores(\_).
- tunnel1\_dpd\_timeout\_action - (Optional, Default clear) The action to take after DPD timeout occurs for the first VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart.
- tunnel2\_dpd\_timeout\_action - (Optional, Default clear) The action to take after DPD timeout occurs for the second VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart.
- tunnel1\_dpd\_timeout\_seconds - (Optional, Default 30) The number of seconds after which a DPD timeout occurs for the first VPN tunnel. Valid value is equal or higher than 30.
- tunnel2\_dpd\_timeout\_seconds - (Optional, Default 30) The number of seconds after which a DPD timeout occurs for the second VPN tunnel. Valid value is equal or higher than 30.
- tunnel1\_enable\_tunnel\_lifecycle\_control - (Optional, Default false) Turn on or off tunnel endpoint lifecycle control feature for the first VPN tunnel. Valid values are true \| false.
- tunnel2\_enable\_tunnel\_lifecycle\_control - (Optional, Default false) Turn on or off tunnel endpoint lifecycle control feature for the second VPN tunnel. Valid values are true \| false.
- tunnel1\_ike\_versions - (Optional) The IKE versions that are permitted for the first VPN tunnel. Valid values are ikev1 \| ikev2.
- tunnel2\_ike\_versions - (Optional) The IKE versions that are permitted for the second VPN tunnel. Valid values are ikev1 \| ikev2.
- tunnel1\_log\_options - (Required) Options for logging VPN tunnel activity:
- enabled - (Required) true if logs need to stored in CloudWatch logs
- log\_group - (Required) The name of the log group.
- retention\_in\_days - (Required) Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
- encrypted - (Required) true if logs need to be encrypted
- tunnel2\_log\_options - (Required) Options for logging VPN tunnel activity:
- enabled - (Required) Required if logs need to stored in CloudWatch logs
- log\_group - (Required) The name of the log group.
- retention\_in\_days - (Required) Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
- encrypted - (Required) true if logs need to be encrypted
- tunnel1\_phase1\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are 2 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel2\_phase1\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are 2 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel1\_phase1\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel2\_phase1\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel1\_phase1\_integrity\_algorithms - (Optional) One or more integrity algorithms that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel2\_phase1\_integrity\_algorithms - (Optional) One or more integrity algorithms that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel1\_phase1\_lifetime\_seconds - (Optional, Default 28800) The lifetime for phase 1 of the IKE negotiation for the first VPN tunnel, in seconds. Valid value is between 900 and 28800.
- tunnel2\_phase1\_lifetime\_seconds - (Optional, Default 28800) The lifetime for phase 1 of the IKE negotiation for the second VPN tunnel, in seconds. Valid value is between 900 and 28800.
- tunnel1\_phase2\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are 2 \| 5 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel2\_phase2\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are 2 \| 5 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel1\_phase2\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel2\_phase2\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel1\_phase2\_integrity\_algorithms - (Optional) List of one or more integrity algorithms that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel2\_phase2\_integrity\_algorithms - (Optional) List of one or more integrity algorithms that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel1\_phase2\_lifetime\_seconds - (Optional, Default 3600) The lifetime for phase 2 of the IKE negotiation for the first VPN tunnel, in seconds. Valid value is between 900 and 3600.
- tunnel2\_phase2\_lifetime\_seconds - (Optional, Default 3600) The lifetime for phase 2 of the IKE negotiation for the second VPN tunnel, in seconds. Valid value is between 900 and 3600.
- tunnel1\_rekey\_fuzz\_percentage - (Optional, Default 100) The percentage of the rekey window for the first VPN tunnel (determined by tunnel1\_rekey\_margin\_time\_seconds) during which the rekey time is randomly selected. Valid value is between 0 and 100.
- tunnel2\_rekey\_fuzz\_percentage - (Optional, Default 100) The percentage of the rekey window for the second VPN tunnel (determined by tunnel2\_rekey\_margin\_time\_seconds) during which the rekey time is randomly selected. Valid value is between 0 and 100.
- tunnel1\_rekey\_margin\_time\_seconds - (Optional, Default 540) The margin time, in seconds, before the phase 2 lifetime expires, during which the AWS side of the first VPN connection performs an IKE rekey. The exact time of the rekey is randomly selected based on the value for tunnel1\_rekey\_fuzz\_percentage. Valid value is between 60 and half of tunnel1\_phase2\_lifetime\_seconds.
- tunnel2\_rekey\_margin\_time\_seconds - (Optional, Default 540) The margin time, in seconds, before the phase 2 lifetime expires, during which the AWS side of the second VPN connection performs an IKE rekey. The exact time of the rekey is randomly selected based on the value for tunnel2\_rekey\_fuzz\_percentage. Valid value is between 60 and half of tunnel2\_phase2\_lifetime\_seconds.
- tunnel1\_replay\_window\_size - (Optional, Default 1024) The number of packets in an IKE replay window for the first VPN tunnel. Valid value is between 64 and 2048.
- tunnel2\_replay\_window\_size - (Optional, Default 1024) The number of packets in an IKE replay window for the second VPN tunnel. Valid value is between 64 and 2048.
- tunnel1\_startup\_action - (Optional, Default add) The action to take when the establishing the tunnel for the first VPN connection. By default, your customer gateway device must initiate the IKE negotiation and bring up the tunnel. Specify start for AWS to initiate the IKE negotiation. Valid values are add \| start.
- tunnel2\_startup\_action - (Optional, Default add) The action to take when the establishing the tunnel for the second VPN connection. By default, your customer gateway device must initiate the IKE negotiation and bring up the tunnel. Specify start for AWS to initiate the IKE negotiation. Valid values are add \| start. | `any` | n/a | yes | +| [vpn\_connection](#input\_vpn\_connection) | VPN connection defined by attributes:
- customer\_gateway\_id - (Required) The ID of the customer gateway.
- type - (Required) The type of VPN connection. The only type AWS supports at this time is "ipsec.1".
- transit\_gateway\_id - (Optional) The ID of the EC2 Transit Gateway.
- static\_routes\_only - (Optional, Default false) Whether the VPN connection uses static routes exclusively. Static routes must be used for devices that don't support BGP.
- enable\_acceleration - (Optional, Default false) Indicate whether to enable acceleration for the VPN connection. Supports only EC2 Transit Gateway.
- tags - (Optional) Tags to apply to the connection. If configured with a provider default\_tags configuration block present, tags with matching keys will overwrite those defined at the provider-level.
- local\_ipv4\_network\_cidr - (Optional, Default 0.0.0.0/0) The IPv4 CIDR on the customer gateway (on-premises) side of the VPN connection.
- local\_ipv6\_network\_cidr - (Optional, Default ::/0) The IPv6 CIDR on the customer gateway (on-premises) side of the VPN connection.
- outside\_ip\_address\_type - (Optional, Default PublicIpv4) Indicates if a Public S2S VPN or Private S2S VPN over AWS Direct Connect. Valid values are PublicIpv4 \| PrivateIpv4
- remote\_ipv4\_network\_cidr - (Optional, Default 0.0.0.0/0) The IPv4 CIDR on the AWS side of the VPN connection.
- remote\_ipv6\_network\_cidr - (Optional, Default ::/0) The IPv6 CIDR on the customer gateway (on-premises) side of the VPN connection.
- transport\_transit\_gateway\_attachment\_id - (Required when outside\_ip\_address\_type is set to PrivateIpv4). The attachment ID of the Transit Gateway attachment to Direct Connect Gateway. The ID is obtained through a data source only.
- tunnel\_inside\_ip\_version - (Optional, Default ipv4) Indicate whether the VPN tunnels process IPv4 or IPv6 traffic. Valid values are ipv4 \| ipv6. ipv6 Supports only EC2 Transit Gateway.
- tunnel1\_inside\_cidr - (Optional) The CIDR block of the inside IP addresses for the first VPN tunnel. Valid value is a size /30 CIDR block from the 169.254.0.0/16 range.
- tunnel2\_inside\_cidr - (Optional) The CIDR block of the inside IP addresses for the second VPN tunnel. Valid value is a size /30 CIDR block from the 169.254.0.0/16 range.
- tunnel1\_inside\_ipv6\_cidr - (Optional) The range of inside IPv6 addresses for the first VPN tunnel. Supports only EC2 Transit Gateway. Valid value is a size /126 CIDR block from the local fd00::/8 range.
- tunnel2\_inside\_ipv6\_cidr - (Optional) The range of inside IPv6 addresses for the second VPN tunnel. Supports only EC2 Transit Gateway. Valid value is a size /126 CIDR block from the local fd00::/8 range.
- tunnel1\_preshared\_key - (Optional) The preshared key of the first VPN tunnel. The preshared key must be between 8 and 64 characters in length and cannot start with zero(0). Allowed characters are alphanumeric characters, periods(.) and underscores(\_).
- tunnel2\_preshared\_key - (Optional) The preshared key of the second VPN tunnel. The preshared key must be between 8 and 64 characters in length and cannot start with zero(0). Allowed characters are alphanumeric characters, periods(.) and underscores(\_).
- tunnel1\_dpd\_timeout\_action - (Optional, Default clear) The action to take after DPD timeout occurs for the first VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart.
- tunnel2\_dpd\_timeout\_action - (Optional, Default clear) The action to take after DPD timeout occurs for the second VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart.
- tunnel1\_dpd\_timeout\_seconds - (Optional, Default 30) The number of seconds after which a DPD timeout occurs for the first VPN tunnel. Valid value is equal or higher than 30.
- tunnel2\_dpd\_timeout\_seconds - (Optional, Default 30) The number of seconds after which a DPD timeout occurs for the second VPN tunnel. Valid value is equal or higher than 30.
- tunnel1\_enable\_tunnel\_lifecycle\_control - (Optional, Default false) Turn on or off tunnel endpoint lifecycle control feature for the first VPN tunnel. Valid values are true \| false.
- tunnel2\_enable\_tunnel\_lifecycle\_control - (Optional, Default false) Turn on or off tunnel endpoint lifecycle control feature for the second VPN tunnel. Valid values are true \| false.
- tunnel1\_ike\_versions - (Optional) The IKE versions that are permitted for the first VPN tunnel. Valid values are ikev1 \| ikev2.
- tunnel2\_ike\_versions - (Optional) The IKE versions that are permitted for the second VPN tunnel. Valid values are ikev1 \| ikev2.
- tunnel1\_log\_options - (Required) Options for logging VPN tunnel activity:
- enabled - (Required) true if logs need to stored in CloudWatch logs
- log\_group - (Required) The name of the log group.
- retention\_in\_days - (Required) Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
- encrypted - (Required) true if logs need to be encrypted
- tunnel2\_log\_options - (Required) Options for logging VPN tunnel activity:
- enabled - (Required) Required if logs need to stored in CloudWatch logs
- log\_group - (Required) The name of the log group.
- retention\_in\_days - (Required) Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
- encrypted - (Required) true if logs need to be encrypted
- tunnel1\_phase1\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are 2 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel2\_phase1\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are 2 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel1\_phase1\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel2\_phase1\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel1\_phase1\_integrity\_algorithms - (Optional) One or more integrity algorithms that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel2\_phase1\_integrity\_algorithms - (Optional) One or more integrity algorithms that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel1\_phase1\_lifetime\_seconds - (Optional, Default 28800) The lifetime for phase 1 of the IKE negotiation for the first VPN tunnel, in seconds. Valid value is between 900 and 28800.
- tunnel2\_phase1\_lifetime\_seconds - (Optional, Default 28800) The lifetime for phase 1 of the IKE negotiation for the second VPN tunnel, in seconds. Valid value is between 900 and 28800.
- tunnel1\_phase2\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are 2 \| 5 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel2\_phase2\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are 2 \| 5 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel1\_phase2\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel2\_phase2\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel1\_phase2\_integrity\_algorithms - (Optional) List of one or more integrity algorithms that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel2\_phase2\_integrity\_algorithms - (Optional) List of one or more integrity algorithms that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel1\_phase2\_lifetime\_seconds - (Optional, Default 3600) The lifetime for phase 2 of the IKE negotiation for the first VPN tunnel, in seconds. Valid value is between 900 and 3600.
- tunnel2\_phase2\_lifetime\_seconds - (Optional, Default 3600) The lifetime for phase 2 of the IKE negotiation for the second VPN tunnel, in seconds. Valid value is between 900 and 3600.
- tunnel1\_rekey\_fuzz\_percentage - (Optional, Default 100) The percentage of the rekey window for the first VPN tunnel (determined by tunnel1\_rekey\_margin\_time\_seconds) during which the rekey time is randomly selected. Valid value is between 0 and 100.
- tunnel2\_rekey\_fuzz\_percentage - (Optional, Default 100) The percentage of the rekey window for the second VPN tunnel (determined by tunnel2\_rekey\_margin\_time\_seconds) during which the rekey time is randomly selected. Valid value is between 0 and 100.
- tunnel1\_rekey\_margin\_time\_seconds - (Optional, Default 540) The margin time, in seconds, before the phase 2 lifetime expires, during which the AWS side of the first VPN connection performs an IKE rekey. The exact time of the rekey is randomly selected based on the value for tunnel1\_rekey\_fuzz\_percentage. Valid value is between 60 and half of tunnel1\_phase2\_lifetime\_seconds.
- tunnel2\_rekey\_margin\_time\_seconds - (Optional, Default 540) The margin time, in seconds, before the phase 2 lifetime expires, during which the AWS side of the second VPN connection performs an IKE rekey. The exact time of the rekey is randomly selected based on the value for tunnel2\_rekey\_fuzz\_percentage. Valid value is between 60 and half of tunnel2\_phase2\_lifetime\_seconds.
- tunnel1\_replay\_window\_size - (Optional, Default 1024) The number of packets in an IKE replay window for the first VPN tunnel. Valid value is between 64 and 2048.
- tunnel2\_replay\_window\_size - (Optional, Default 1024) The number of packets in an IKE replay window for the second VPN tunnel. Valid value is between 64 and 2048.
- tunnel1\_startup\_action - (Optional, Default add) The action to take when the establishing the tunnel for the first VPN connection. By default, your customer gateway device must initiate the IKE negotiation and bring up the tunnel. Specify start for AWS to initiate the IKE negotiation. Valid values are add \| start.
- tunnel2\_startup\_action - (Optional, Default add) The action to take when the establishing the tunnel for the second VPN connection. By default, your customer gateway device must initiate the IKE negotiation and bring up the tunnel. Specify start for AWS to initiate the IKE negotiation. Valid values are add \| start. |
object({
name = optional(string, "")
customer\_gateway\_id = string
type = optional(string, "ipsec.1")
transit\_gateway\_id = optional(string)
static\_routes\_only = optional(bool, false)
enable\_acceleration = optional(bool, false)
tags = optional(map(string))
local\_ipv4\_network\_cidr = optional(string, "0.0.0.0/0")
local\_ipv6\_network\_cidr = optional(string, "::/0")
outside\_ip\_address\_type = optional(string, "PublicIpv4")
remote\_ipv4\_network\_cidr = optional(string, "0.0.0.0/0")
remote\_ipv6\_network\_cidr = optional(string, "::/0")
tunnel\_inside\_ip\_version = optional(string, "ipv4")
tunnel1\_inside\_cidr = optional(string)
tunnel2\_inside\_cidr = optional(string)
tunnel1\_inside\_ipv6\_cidr = optional(string)
tunnel2\_inside\_ipv6\_cidr = optional(string)
tunnel1\_preshared\_key = optional(string)
tunnel2\_preshared\_key = optional(string)
tunnel1\_dpd\_timeout\_action = optional(string)
tunnel2\_dpd\_timeout\_action = optional(string)
tunnel1\_dpd\_timeout\_seconds = optional(number, 30)
tunnel2\_dpd\_timeout\_seconds = optional(number, 30)
tunnel1\_enable\_tunnel\_lifecycle\_control = optional(bool)
tunnel2\_enable\_tunnel\_lifecycle\_control = optional(bool)
tunnel1\_ike\_versions = optional(string)
tunnel2\_ike\_versions = optional(string)
tunnel1\_log\_options = object({
enabled = bool
log\_group = string
retention\_in\_days = number
encrypted = bool
})
tunnel2\_log\_options = object({
enabled = bool
log\_group = string
retention\_in\_days = number
encrypted = bool
})
tunnel1\_phase1\_dh\_group\_numbers = optional(list(string))
tunnel2\_phase1\_dh\_group\_numbers = optional(list(string))
tunnel1\_phase1\_encryption\_algorithms = optional(list(string))
tunnel2\_phase1\_encryption\_algorithms = optional(list(string))
tunnel1\_phase1\_integrity\_algorithms = optional(list(string))
tunnel2\_phase1\_integrity\_algorithms = optional(list(string))
tunnel1\_phase1\_lifetime\_seconds = optional(number, 28800)
tunnel2\_phase1\_lifetime\_seconds = optional(number, 28800)
tunnel1\_phase2\_dh\_group\_numbers = optional(list(string))
tunnel2\_phase2\_dh\_group\_numbers = optional(list(string))
tunnel1\_phase2\_encryption\_algorithms = optional(list(string))
tunnel2\_phase2\_encryption\_algorithms = optional(list(string))
tunnel1\_phase2\_integrity\_algorithms = optional(list(string))
tunnel2\_phase2\_integrity\_algorithms = optional(list(string))
tunnel1\_phase2\_lifetime\_seconds = optional(number, 3600)
tunnel2\_phase2\_lifetime\_seconds = optional(number, 3600)
tunnel1\_rekey\_fuzz\_percentage = optional(number, 100)
tunnel2\_rekey\_fuzz\_percentage = optional(number, 100)
tunnel1\_rekey\_margin\_time\_seconds = optional(number, 540)
tunnel2\_rekey\_margin\_time\_seconds = optional(number, 540)
tunnel1\_replay\_window\_size = optional(number, 1024)
tunnel2\_replay\_window\_size = optional(number, 1024)
tunnel1\_startup\_action = optional(string, "add")
tunnel2\_startup\_action = optional(string, "add")
})
| n/a | yes | | [vpn\_gateway\_id](#input\_vpn\_gateway\_id) | Virtual Private Gateway's ID used by VPN connection | `string` | n/a | yes | ### Outputs diff --git a/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/2b8d22f5-ebf8-462e-90ff-cbed9084afd0.png b/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/2b8d22f5-ebf8-462e-90ff-cbed9084afd0.png new file mode 100644 index 000000000..467564b57 Binary files /dev/null and b/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/2b8d22f5-ebf8-462e-90ff-cbed9084afd0.png differ diff --git a/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_centralized_design.md b/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_centralized_design.md new file mode 100644 index 000000000..5447428e3 --- /dev/null +++ b/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_centralized_design.md @@ -0,0 +1,166 @@ +--- +hide_title: true +id: cloudngfw_centralized_design +keywords: +- pan-os +- panos +- firewall +- configuration +- terraform +- vmseries +- vm-series +- swfw +- software-firewalls +- aws +pagination_next: null +pagination_prev: null +sidebar_label: Centralized Design +title: Centralized Design model +--- + +# Centralized Design model +- Separated Firewall Cluster(s) to inspect applications in spoke VPCs. +- Centralized Inbound VPC to inspect ingress traffic. +- Transparently insert inspection in your application VPCs for Ingress, Egress and East-West Traffic. +- TGW resource is required. + +[![GitHub Logo](/img/view_on_github.png)](https://github.com/PaloAltoNetworks/terraform-aws-swfw-modules/tree/main/examples/cloudngfw_centralized_design) [![Terraform Logo](/img/view_on_terraform_registry.png)](https://registry.terraform.io/modules/PaloAltoNetworks/swfw-modules/aws/latest/examples/cloudngfw_centralized_design) + +## Prerequsite +- Enable Programmatic Access +To use the Terraform provider, you must first enable the Programmatic Access for your Cloud NGFW tenant. You can check this by navigating to the Settings section of the Cloud NGFW console. The steps to do this can be found [here](https://pan.dev/cloudngfw/aws/api/). +- Cloud NGFW assuming role +You will authenticate against your Cloud NGFW by assuming roles in your AWS account that are allowed to make API calls to the AWS API Gateway service. The associated tags with the roles dictate the type of Cloud NGFW programmatic access granted — Firewall Admin, RuleStack Admin, or Global Rulestack Admin. +``` +resource "aws_iam_role" "ngfw_role" { + name = "CloudNGFWRole" + + inline_policy { + name = "apigateway_policy" + + policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [ + { + "Effect" : "Allow", + "Action" : [ + "execute-api:Invoke", + "execute-api:ManageConnections" + ], + "Resource" : "arn:aws:execute-api:*:*:*" + } + ] + }) + } + + assume_role_policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [ + { + "Sid" : "", + "Effect" : "Allow", + "Principal" : { + "Service" : "apigateway.amazonaws.com" + }, + "Action" : "sts:AssumeRole" + }, + { + "Sid" : "", + "Effect" : "Allow", + "Principal" : { + "AWS" : [ + + ] + }, + "Action" : "sts:AssumeRole" + } + ] + }) + + tags = { + CloudNGFWRulestackAdmin = "Yes" + CloudNGFWFirewallAdmin = "Yes" + CloudNGFWGlobalRulestackAdmin = "Yes" + } +} + +``` +- Update appriopate values for terraform variables ```var.provider_account``` and ``var.provider_role``. + +## Spoke VMs + +For the proposed example, the Spoke VMs are supporting ssm-agent. In addition, the VM ```user_data``` contains an installation of httpd service.
+To enable access from the session manager, the Internet connection for a public endpoint is required. + +## Reference + +### Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.5.0, < 2.0.0 | +| [aws](#requirement\_aws) | ~> 5.17 | +| [cloudngfwaws](#requirement\_cloudngfwaws) | 2.0.20 | +| [time](#requirement\_time) | 0.11.1 | + +### Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~> 5.17 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| [app\_alb](#module\_app\_alb) | ../../modules/alb | n/a | +| [cloudngfw](#module\_cloudngfw) | ../../modules/cloudngfw | n/a | +| [gwlbe\_endpoint](#module\_gwlbe\_endpoint) | ../../modules/gwlb_endpoint_set | n/a | +| [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | +| [subnet\_sets](#module\_subnet\_sets) | ../../modules/subnet_set | n/a | +| [transit\_gateway](#module\_transit\_gateway) | ../../modules/transit_gateway | n/a | +| [transit\_gateway\_attachment](#module\_transit\_gateway\_attachment) | ../../modules/transit_gateway_attachment | n/a | +| [vpc](#module\_vpc) | ../../modules/vpc | n/a | +| [vpc\_routes](#module\_vpc\_routes) | ../../modules/vpc_route | n/a | + +### Resources + +| Name | Type | +|------|------| +| [aws_ec2_transit_gateway_route.from_spokes_to_security](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route) | resource | +| [aws_ec2_transit_gateway_route_table_propagation.spokes_to_ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route_table_propagation) | resource | +| [aws_iam_instance_profile.spoke_vm_iam_instance_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_role.spoke_vm_ec2_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.spoke_vm_iam_instance_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_instance.spoke_vms](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource | +| [aws_ami.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_ebs_default_kms_key.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ebs_default_kms_key) | data source | +| [aws_kms_key.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_key) | data source | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [cloudngfws](#input\_cloudngfws) | A map defining Cloud NGFWs.

Following properties are available:
- `name` : name of CloudNGFW
- `subnet_group`: key of the subnet\_group
- `vpc` : key of the VPC
- `description`: Use for internal purposes.
- `security_rules`: Security Rules definition.
- `log_profiles`: Log Profile definition.

Example:
cloudngfws = {
cloudngfws\_security = {
name = "cloudngfw01"
subnet\_group = "app\_gwlbe"
vpc = "app\_vpc"
description = "description"
security\_rules =
{
rule\_1 = {
rule\_list = "LocalRule"
priority = 3
name = "tf-security-rule"
description = "Also configured by Terraform"
source\_cidrs = ["any"]
destination\_cidrs = ["0.0.0.0/0"]
negate\_destination = false
protocol = "application-default"
applications = ["any"]
category\_feeds = null
category\_url\_category\_names = null
action = "Allow"
logging = true
audit\_comment = "initial config"
}
}
log\_profiles = {
dest\_1 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "THREAT"
}
dest\_2 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "TRAFFIC"
}
dest\_3 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "DECRYPTION"
}
}
profile\_config = {
anti\_spyware = "BestPractice"
anti\_virus = "BestPractice"
vulnerability = "BestPractice"
file\_blocking = "BestPractice"
url\_filtering = "BestPractice"
}
}
}
|
map(object({
name = string
subnet\_group = string
vpc = string
description = optional(string, "Palo Alto Cloud NGFW")
security\_rules = map(any)
log\_profiles = map(any)
profile\_config = map(any)
}))
| `{}` | no | +| [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `any` | n/a | yes | +| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `custom_names`: Optional map of names of the VPC Endpoints, used to override the default naming generated from the input `name`.
Each key is the Availability Zone identifier, for example `us-east-1b`.
- `gwlb`: key of GWLB. Required when GWLB Endpoint must connect to GWLB's service name
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint
- `cloudngfw_key`(optional): Key of the Cloud NGFW. Required when GWLB Endpoint must connect to Cloud NGFW's service name

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
custom\_names = optional(map(string), {})
gwlb = optional(string)
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
delay = optional(number, 0)
tags = optional(map(string))
cloudngfw\_key = optional(string)
}))
| `{}` | no | +| [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | n/a | yes | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | +| [provider\_account](#input\_provider\_account) | The AWS Account where the resources should be deployed. | `string` | n/a | yes | +| [provider\_role](#input\_provider\_role) | The predifined AWS assumed role for CloudNGFW. | `string` | n/a | yes | +| [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | +| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = map(object({
protocol = optional(string, "HTTP")
port = optional(number, 80)
health\_check\_port = optional(string, "80")
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
health\_check\_interval = optional(number, 10)
listener\_rules = map(object({
target\_protocol = string
target\_port = number
path\_pattern = list(string)
}))
}))
vms = list(string)
target\_group\_az = optional(string, "all")
vpc = string
subnet\_group = string
security\_groups = string
}))
| `{}` | no | +| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 VM type

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t3.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = optional(string, "t3.micro")
}))
| `{}` | no | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | +| [tgw\_attachments](#input\_tgw\_attachments) | A object defining Transit Gateway Attachments.

Following properties are available:
- `tgw_key`: key of the TGW to be attached
- `create`: set to false, if existing TGW attachment needs to be reused
- `id`: id of existing TGW
- `security_vpc_attachment`: set to true if default route from spoke VPCs towards
this attachment should be created
- `name`: name of the TGW attachment to create or use
- `asn`: ASN number
- `vpc`: key of the attaching VPC
- `route_table`: route table key created under TGW taht must be associated with attachment
- `propagate_routes_to`: route table key created under TGW

Example:
tgw\_attachments = {
security = {
tgw\_key = "tgw"
name = "vmseries"
vpc = "security\_vpc"
subnet\_group = "tgw\_attach"
route\_table = "from\_security\_vpc"
propagate\_routes\_to = "from\_spoke\_vpc"
}
}
|
map(object({
tgw\_key = string
create = optional(bool, true)
id = optional(string)
security\_vpc\_attachment = optional(bool, false)
name = string
vpc = string
subnet\_group = string
route\_table = string
propagate\_routes\_to = string
appliance\_mode\_support = optional(string, "enable")
dns\_support = optional(string, null)
tags = optional(map(string))
}))
| `{}` | no | +| [tgws](#input\_tgws) | A object defining Transit Gateway.

Following properties are available:
- `create`: set to false, if existing TGW needs to be reused
- `id`: id of existing TGW
- `name`: name of TGW to create or use
- `asn`: ASN number
- `route_tables`: map of route tables

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route\_tables = {
"from\_security\_vpc" = {
create = true
name = "from\_security"
}
}
}
|
map(object({
create = optional(bool, true)
id = optional(string)
name = string
asn = string
route\_tables = map(object({
create = bool
name = string
}))
}))
| `{}` | no | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | + +### Outputs + +| Name | Description | +|------|-------------| +| [app\_inspected\_dns\_name](#output\_app\_inspected\_dns\_name) | FQDN of App Load Balancers.
Can be used in Cloud NGFW configuration to balance traffic between the application instances. | +| [cloudngfws](#output\_cloudngfws) | #### Cloud NGFW ##### | + \ No newline at end of file diff --git a/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_combined_design.md b/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_combined_design.md index 18490ab66..7f3b2ff2f 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_combined_design.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_combined_design.md @@ -102,7 +102,7 @@ To enable access from the session manager, the Internet connection for a public |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.0, < 2.0.0 | | [aws](#requirement\_aws) | ~> 5.17 | -| [cloudngfwaws](#requirement\_cloudngfwaws) | 2.0.6 | +| [cloudngfwaws](#requirement\_cloudngfwaws) | 2.0.20 | | [time](#requirement\_time) | 0.11.1 | ### Providers @@ -115,11 +115,11 @@ To enable access from the session manager, the Internet connection for a public | Name | Source | Version | |------|--------|---------| +| [app\_alb](#module\_app\_alb) | ../../modules/alb | n/a | +| [app\_nlb](#module\_app\_nlb) | ../../modules/nlb | n/a | | [cloudngfw](#module\_cloudngfw) | ../../modules/cloudngfw | n/a | | [gwlbe\_endpoint](#module\_gwlbe\_endpoint) | ../../modules/gwlb_endpoint_set | n/a | | [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | -| [public\_alb](#module\_public\_alb) | ../../modules/alb | n/a | -| [public\_nlb](#module\_public\_nlb) | ../../modules/nlb | n/a | | [subnet\_sets](#module\_subnet\_sets) | ../../modules/subnet_set | n/a | | [transit\_gateway](#module\_transit\_gateway) | ../../modules/transit_gateway | n/a | | [transit\_gateway\_attachment](#module\_transit\_gateway\_attachment) | ../../modules/transit_gateway_attachment | n/a | @@ -144,20 +144,21 @@ To enable access from the session manager, the Internet connection for a public | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [cloudngfws](#input\_cloudngfws) | A map defining Cloud NGFWs.

Following properties are available:
- `name` : name of CloudNGFW
- `vpc_subnet` : key of the VPC and subnet connected by '-' character
- `vpc` : key of the VPC
- `description`: Use for internal purposes.
- `security_rules`: Security Rules definition.
- `log_profiles`: Log Profile definition.

Example:
cloudngfws = {
cloudngfws\_security = {
name = "cloudngfw01"
vpc\_subnet = "app\_vpc-app\_gwlbe"
vpc = "app\_vpc"
description = "description"
security\_rules =
{
rule\_1 = {
rule\_list = "LocalRule"
priority = 3
name = "tf-security-rule"
description = "Also configured by Terraform"
source\_cidrs = ["any"]
destination\_cidrs = ["0.0.0.0/0"]
negate\_destination = false
protocol = "application-default"
applications = ["any"]
category\_feeds = null
category\_url\_category\_names = null
action = "Allow"
logging = true
audit\_comment = "initial config"
}
}
log\_profiles = {
dest\_1 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "THREAT"
}
dest\_2 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "TRAFFIC"
}
dest\_3 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "DECRYPTION"
}
}
profile\_config = {
anti\_spyware = "BestPractice"
anti\_virus = "BestPractice"
vulnerability = "BestPractice"
file\_blocking = "BestPractice"
url\_filtering = "BestPractice"
}
}
}
|
map(object({
name = string
vpc\_subnet = string
vpc = string
description = string
security\_rules = map(any)
log\_profiles = map(any)
profile\_config = map(any)
}))
| `{}` | no | +| [cloudngfws](#input\_cloudngfws) | A map defining Cloud NGFWs.

Following properties are available:
- `name` : name of CloudNGFW
- `subnet_group`: key of the subnet\_group
- `vpc` : key of the VPC
- `description`: Use for internal purposes.
- `security_rules`: Security Rules definition.
- `log_profiles`: Log Profile definition.

Example:
cloudngfws = {
cloudngfws\_security = {
name = "cloudngfw01"
vpc\_subnet = "app\_vpc-app\_gwlbe"
vpc = "app\_vpc"
description = "description"
security\_rules =
{
rule\_1 = {
rule\_list = "LocalRule"
priority = 3
name = "tf-security-rule"
description = "Also configured by Terraform"
source\_cidrs = ["any"]
destination\_cidrs = ["0.0.0.0/0"]
negate\_destination = false
protocol = "application-default"
applications = ["any"]
category\_feeds = null
category\_url\_category\_names = null
action = "Allow"
logging = true
audit\_comment = "initial config"
}
}
log\_profiles = {
dest\_1 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "THREAT"
}
dest\_2 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "TRAFFIC"
}
dest\_3 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "DECRYPTION"
}
}
profile\_config = {
anti\_spyware = "BestPractice"
anti\_virus = "BestPractice"
vulnerability = "BestPractice"
file\_blocking = "BestPractice"
url\_filtering = "BestPractice"
}
}
}
|
map(object({
name = string
subnet\_group = string
vpc = string
description = optional(string, "Palo Alto Cloud NGFW")
security\_rules = map(any)
log\_profiles = map(any)
profile\_config = map(any)
}))
| `{}` | no | | [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `any` | n/a | yes | -| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `gwlb`: key of GWLB
- `vpc`: key of VPC
- `subnet`: key of the subnet
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet` : subnet to which traffic from IGW is routed to the GWLB endpoint

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet = "gwlbe\_eastwest"
act\_as\_next\_hop = false
delay = 60
cloudngfw = "cloudngfw"
}
}
|
map(object({
name = string
vpc = string
subnet = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet = optional(string)
delay = number
cloudngfw = string
}))
| `{}` | no | +| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `custom_names`: Optional map of names of the VPC Endpoints, used to override the default naming generated from the input `name`.
Each key is the Availability Zone identifier, for example `us-east-1b`.
- `gwlb`: key of GWLB. Required when GWLB Endpoint must connect to GWLB's service name
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint
- `cloudngfw_key`(optional): Key of the Cloud NGFW. Required when GWLB Endpoint must connect to Cloud NGFW's service name

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
custom\_names = optional(map(string), {})
gwlb = optional(string)
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
delay = optional(number, 0)
tags = optional(map(string))
cloudngfw\_key = optional(string)
}))
| `{}` | no | | [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | n/a | yes | -| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `name`: name of NAT Gateway
- `vpc`: key of the VPC
- `subnet`: key of the subnet

Example:
natgws = {
security\_nat\_gw = {
name = "natgw"
vpc = "security\_vpc"
subnet = "natgw"
}
}
|
map(object({
name = string
vpc = string
subnet = string
}))
| `{}` | no | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | | [provider\_account](#input\_provider\_account) | The AWS Account where the resources should be deployed. | `string` | n/a | yes | | [provider\_role](#input\_provider\_role) | The predifined AWS assumed role for CloudNGFW. | `string` | n/a | yes | | [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | -| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = any
vms = list(string)
vpc = string
subnet = string
security\_groups = string
}))
| n/a | yes | -| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `vpc`: key of the VPC
- `subnet`: key of the subnet
- `vms`: keys of spoke VMs

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
vpc = string
subnet = string
vms = list(string)
}))
| `{}` | no | -| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `vpc`: name of the VPC (needs to be one of the keys in map `vpcs`)
- `subnet`: key of the subnet
- `security_group`: security group assigned to ENI used by VM
- `type`: EC2 type VM

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet = "app1\_vm"
security\_group = "app1\_vm"
type = "t2.micro"
}
}
|
map(object({
az = string
vpc = string
subnet = string
security\_group = string
type = string
}))
| `{}` | no | -| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | -| [tgw](#input\_tgw) | A object defining Transit Gateway.

Following properties are available:
- `create`: set to false, if existing TGW needs to be reused
- `id`: id of existing TGW or null
- `name`: name of TGW to create or use
- `asn`: ASN number
- `route_tables`: map of route tables
- `attachments`: map of TGW attachments

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route\_tables = {
"from\_security\_vpc" = {
create = true
name = "from\_security"
}
}
attachments = {
security = {
name = "vmseries"
vpc = "security\_vpc"
subnet = "tgw\_attach"
route\_table = "from\_security\_vpc"
propagate\_routes\_to = ["from\_spoke\_vpc"]
}
}
}
|
object({
create = bool
id = string
name = string
asn = string
route\_tables = map(object({
create = bool
name = string
}))
attachments = map(object({
name = string
vpc = string
subnet = string
route\_table = string
propagate\_routes\_to = list(string)
}))
})
| n/a | yes | -| [vpcs](#input\_vpcs) | A 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` - VPC key
- `subnet` - subnet key
- `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 }
"10.104.128.0/24" = { az = "eu-central-1b", set = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet = "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 = 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
set = 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 = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
}))
}))
| `{}` | no | +| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = map(object({
protocol = optional(string, "HTTP")
port = optional(number, 80)
health\_check\_port = optional(string, "80")
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
health\_check\_interval = optional(number, 10)
listener\_rules = map(object({
target\_protocol = string
target\_port = number
path\_pattern = list(string)
}))
}))
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| `{}` | no | +| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `name`: Name of the NLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs
- `internal_lb`(optional): flag to switch between internet\_facing and internal NLB
- `balance_rules` (optional): Rules defining the method of traffic balancing

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
vms = list(string)
internal\_lb = optional(bool, false)
balance\_rules = map(object({
protocol = string
port = string
stickiness = optional(bool, true)
}))
}))
| `{}` | no | +| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 VM type

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t3.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = optional(string, "t3.micro")
}))
| `{}` | no | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | `""` | no | +| [tgw\_attachments](#input\_tgw\_attachments) | A object defining Transit Gateway Attachments.

Following properties are available:
- `tgw_key`: key of the TGW to be attached
- `create`: set to false, if existing TGW attachment needs to be reused
- `id`: id of existing TGW
- `security_vpc_attachment`: set to true if default route from spoke VPCs towards
this attachment should be created
- `name`: name of the TGW attachment to create or use
- `asn`: ASN number
- `vpc`: key of the attaching VPC
- `route_table`: route table key created under TGW taht must be associated with attachment
- `propagate_routes_to`: route table key created under TGW

Example:
tgw\_attachments = {
security = {
tgw\_key = "tgw"
name = "vmseries"
vpc = "security\_vpc"
subnet\_group = "tgw\_attach"
route\_table = "from\_security\_vpc"
propagate\_routes\_to = "from\_spoke\_vpc"
}
}
|
map(object({
tgw\_key = string
create = optional(bool, true)
id = optional(string)
security\_vpc\_attachment = optional(bool, false)
name = string
vpc = string
subnet\_group = string
route\_table = string
propagate\_routes\_to = string
appliance\_mode\_support = optional(string, "enable")
dns\_support = optional(string, null)
tags = optional(map(string))
}))
| `{}` | no | +| [tgws](#input\_tgws) | A object defining Transit Gateway.

Following properties are available:
- `create`: set to false, if existing TGW needs to be reused
- `id`: id of existing TGW
- `name`: name of TGW to create or use
- `asn`: ASN number
- `route_tables`: map of route tables

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route\_tables = {
"from\_security\_vpc" = {
create = true
name = "from\_security"
}
}
}
|
map(object({
create = optional(bool, true)
id = optional(string)
name = string
asn = string
route\_tables = map(object({
create = bool
name = string
}))
}))
| `{}` | no | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | ### Outputs diff --git a/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_distributed_design.md b/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_distributed_design.md new file mode 100644 index 000000000..31e0ed4d5 --- /dev/null +++ b/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_distributed_design.md @@ -0,0 +1,161 @@ +--- +hide_title: true +id: cloudngfw_distributed_design +keywords: +- pan-os +- panos +- firewall +- configuration +- terraform +- vmseries +- vm-series +- swfw +- software-firewalls +- aws +pagination_next: null +pagination_prev: null +sidebar_label: Distributed Design +title: Distributed Design model +--- + +# Distributed Design model +- Cloud NGFW is deployed for each VPC which requires protection +- Reduces the possibility of misconfiguration and limits the scope of impact +- Each VPC is protected individually and blast radius is reduced through VPC isolation + +![image](2b8d22f5-ebf8-462e-90ff-cbed9084afd0.png) + +[![GitHub Logo](/img/view_on_github.png)](https://github.com/PaloAltoNetworks/terraform-aws-swfw-modules/tree/main/examples/cloudngfw_distributed_design) [![Terraform Logo](/img/view_on_terraform_registry.png)](https://registry.terraform.io/modules/PaloAltoNetworks/swfw-modules/aws/latest/examples/cloudngfw_distributed_design) + +## Prerequsite +- Enable Programmatic Access +To use the Terraform provider, you must first enable the Programmatic Access for your Cloud NGFW tenant. You can check this by navigating to the Settings section of the Cloud NGFW console. The steps to do this can be found [here](https://pan.dev/cloudngfw/aws/api/). +- Cloud NGFW assuming role +You will authenticate against your Cloud NGFW by assuming roles in your AWS account that are allowed to make API calls to the AWS API Gateway service. The associated tags with the roles dictate the type of Cloud NGFW programmatic access granted — Firewall Admin, RuleStack Admin, or Global Rulestack Admin. +``` +resource "aws_iam_role" "ngfw_role" { + name = "CloudNGFWRole" + + inline_policy { + name = "apigateway_policy" + + policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [ + { + "Effect" : "Allow", + "Action" : [ + "execute-api:Invoke", + "execute-api:ManageConnections" + ], + "Resource" : "arn:aws:execute-api:*:*:*" + } + ] + }) + } + + assume_role_policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [ + { + "Sid" : "", + "Effect" : "Allow", + "Principal" : { + "Service" : "apigateway.amazonaws.com" + }, + "Action" : "sts:AssumeRole" + }, + { + "Sid" : "", + "Effect" : "Allow", + "Principal" : { + "AWS" : [ + + ] + }, + "Action" : "sts:AssumeRole" + } + ] + }) + + tags = { + CloudNGFWRulestackAdmin = "Yes" + CloudNGFWFirewallAdmin = "Yes" + CloudNGFWGlobalRulestackAdmin = "Yes" + } +} + +``` +- Update appriopate values for terraform variables ```var.provider_account``` and ``var.provider_role``. + +## Spoke VMs + +For the proposed example, the Spoke VMs are supporting ssm-agent. In addition, the VM ```user_data``` contains an installation of httpd service.
+To enable access from the session manager, the Internet connection for a public endpoint is required. + +## Reference + +### Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.5.0, < 2.0.0 | +| [aws](#requirement\_aws) | ~> 5.17 | +| [cloudngfwaws](#requirement\_cloudngfwaws) | 2.0.20 | +| [time](#requirement\_time) | 0.11.1 | + +### Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~> 5.17 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| [app\_alb](#module\_app\_alb) | ../../modules/alb | n/a | +| [cloudngfw](#module\_cloudngfw) | ../../modules/cloudngfw | n/a | +| [gwlbe\_endpoint](#module\_gwlbe\_endpoint) | ../../modules/gwlb_endpoint_set | n/a | +| [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | +| [subnet\_sets](#module\_subnet\_sets) | ../../modules/subnet_set | n/a | +| [vpc](#module\_vpc) | ../../modules/vpc | n/a | +| [vpc\_routes](#module\_vpc\_routes) | ../../modules/vpc_route | n/a | + +### Resources + +| Name | Type | +|------|------| +| [aws_iam_instance_profile.spoke_vm_iam_instance_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_role.spoke_vm_ec2_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.spoke_vm_iam_instance_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_instance.spoke_vms](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource | +| [aws_ami.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_ebs_default_kms_key.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ebs_default_kms_key) | data source | +| [aws_kms_key.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_key) | data source | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [cloudngfws](#input\_cloudngfws) | A map defining Cloud NGFWs.

Following properties are available:
- `name` : name of CloudNGFW
- `vpc_subnet` : key of the VPC and subnet connected by '-' character
- `vpc` : key of the VPC
- `description`: Use for internal purposes.
- `security_rules`: Security Rules definition.
- `log_profiles`: Log Profile definition.

Example:
cloudngfws = {
cloudngfws\_security = {
name = "cloudngfw01"
vpc\_subnet = "app\_vpc-app\_gwlbe"
vpc = "app\_vpc"
description = "description"
security\_rules =
{
rule\_1 = {
rule\_list = "LocalRule"
priority = 3
name = "tf-security-rule"
description = "Also configured by Terraform"
source\_cidrs = ["any"]
destination\_cidrs = ["0.0.0.0/0"]
negate\_destination = false
protocol = "application-default"
applications = ["any"]
category\_feeds = null
category\_url\_category\_names = null
action = "Allow"
logging = true
audit\_comment = "initial config"
}
}
log\_profiles = {
dest\_1 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "THREAT"
}
dest\_2 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "TRAFFIC"
}
dest\_3 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "DECRYPTION"
}
}
profile\_config = {
anti\_spyware = "BestPractice"
anti\_virus = "BestPractice"
vulnerability = "BestPractice"
file\_blocking = "BestPractice"
url\_filtering = "BestPractice"
}
}
}
|
map(object({
name = string
subnet\_group = string
vpc = string
description = optional(string, "Palo Alto Cloud NGFW")
security\_rules = map(any)
log\_profiles = map(any)
profile\_config = map(any)
}))
| `{}` | no | +| [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `any` | n/a | yes | +| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `custom_names`: Optional map of names of the VPC Endpoints, used to override the default naming generated from the input `name`.
Each key is the Availability Zone identifier, for example `us-east-1b`.
- `gwlb`: key of GWLB. Required when GWLB Endpoint must connect to GWLB's service name
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint
- `cloudngfw_key`(optional): Key of the Cloud NGFW. Required when GWLB Endpoint must connect to Cloud NGFW's service name

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
custom\_names = optional(map(string), {})
gwlb = optional(string)
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
delay = optional(number, 0)
tags = optional(map(string))
cloudngfw\_key = optional(string)
}))
| `{}` | no | +| [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | n/a | yes | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | +| [provider\_account](#input\_provider\_account) | The AWS Account where the resources should be deployed. | `string` | n/a | yes | +| [provider\_role](#input\_provider\_role) | The predifined AWS assumed role for CloudNGFW. | `string` | n/a | yes | +| [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | +| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
name = optional(string)
rules = map(object({
protocol = optional(string, "HTTP")
port = optional(number, 80)
health\_check\_port = optional(string, "80")
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
health\_check\_interval = optional(number, 10)
listener\_rules = map(object({
target\_protocol = string
target\_port = number
path\_pattern = list(string)
}))
}))
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| `{}` | no | +| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 VM type

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t3.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = optional(string, "t3.micro")
}))
| `{}` | no | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | + +### Outputs + +| Name | Description | +|------|-------------| +| [application\_load\_balancers](#output\_application\_load\_balancers) | FQDNs of Application Load Balancers | +| [cloudngfws](#output\_cloudngfws) | Cloud NGFW service name | + \ No newline at end of file diff --git a/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_isolated_design.md b/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_isolated_design.md index 83126a457..da8382dc9 100644 --- a/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_isolated_design.md +++ b/products/terraform/docs/swfw/aws/cloudngfw/reference-architectures/cloudngfw_isolated_design.md @@ -101,7 +101,7 @@ To enable access from the session manager, the Internet connection for a public |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.0, < 2.0.0 | | [aws](#requirement\_aws) | ~> 5.17 | -| [cloudngfwaws](#requirement\_cloudngfwaws) | 2.0.6 | +| [cloudngfwaws](#requirement\_cloudngfwaws) | 2.0.20 | | [time](#requirement\_time) | 0.11.1 | ### Providers @@ -114,11 +114,11 @@ To enable access from the session manager, the Internet connection for a public | Name | Source | Version | |------|--------|---------| +| [app\_alb](#module\_app\_alb) | ../../modules/alb | n/a | +| [app\_nlb](#module\_app\_nlb) | ../../modules/nlb | n/a | | [cloudngfw](#module\_cloudngfw) | ../../modules/cloudngfw | n/a | | [gwlbe\_endpoint](#module\_gwlbe\_endpoint) | ../../modules/gwlb_endpoint_set | n/a | | [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | -| [public\_alb](#module\_public\_alb) | ../../modules/alb | n/a | -| [public\_nlb](#module\_public\_nlb) | ../../modules/nlb | n/a | | [subnet\_sets](#module\_subnet\_sets) | ../../modules/subnet_set | n/a | | [vpc](#module\_vpc) | ../../modules/vpc | n/a | | [vpc\_routes](#module\_vpc\_routes) | ../../modules/vpc_route | n/a | @@ -140,19 +140,19 @@ To enable access from the session manager, the Internet connection for a public | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [cloudngfws](#input\_cloudngfws) | A map defining Cloud NGFWs.

Following properties are available:
- `name` : name of CloudNGFW
- `vpc_subnet` : key of the VPC and subnet connected by '-' character
- `vpc` : key of the VPC
- `description`: Use for internal purposes.
- `security_rules`: Security Rules definition.
- `log_profiles`: Log Profile definition.

Example:
cloudngfws = {
cloudngfws\_security = {
name = "cloudngfw01"
vpc\_subnet = "app\_vpc-app\_gwlbe"
vpc = "app\_vpc"
description = "description"
security\_rules =
{
rule\_1 = {
rule\_list = "LocalRule"
priority = 3
name = "tf-security-rule"
description = "Also configured by Terraform"
source\_cidrs = ["any"]
destination\_cidrs = ["0.0.0.0/0"]
negate\_destination = false
protocol = "application-default"
applications = ["any"]
category\_feeds = null
category\_url\_category\_names = null
action = "Allow"
logging = true
audit\_comment = "initial config"
}
}
log\_profiles = {
dest\_1 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "THREAT"
}
dest\_2 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "TRAFFIC"
}
dest\_3 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "DECRYPTION"
}
}
profile\_config = {
anti\_spyware = "BestPractice"
anti\_virus = "BestPractice"
vulnerability = "BestPractice"
file\_blocking = "BestPractice"
url\_filtering = "BestPractice"
}
}
}
|
map(object({
name = string
vpc\_subnet = string
vpc = string
description = string
security\_rules = map(any)
log\_profiles = map(any)
profile\_config = map(any)
}))
| `{}` | no | +| [cloudngfws](#input\_cloudngfws) | A map defining Cloud NGFWs.

Following properties are available:
- `name` : name of CloudNGFW
- `vpc_subnet` : key of the VPC and subnet connected by '-' character
- `vpc` : key of the VPC
- `description`: Use for internal purposes.
- `security_rules`: Security Rules definition.
- `log_profiles`: Log Profile definition.

Example:
cloudngfws = {
cloudngfws\_security = {
name = "cloudngfw01"
vpc\_subnet = "app\_vpc-app\_gwlbe"
vpc = "app\_vpc"
description = "description"
security\_rules =
{
rule\_1 = {
rule\_list = "LocalRule"
priority = 3
name = "tf-security-rule"
description = "Also configured by Terraform"
source\_cidrs = ["any"]
destination\_cidrs = ["0.0.0.0/0"]
negate\_destination = false
protocol = "application-default"
applications = ["any"]
category\_feeds = null
category\_url\_category\_names = null
action = "Allow"
logging = true
audit\_comment = "initial config"
}
}
log\_profiles = {
dest\_1 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "THREAT"
}
dest\_2 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "TRAFFIC"
}
dest\_3 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "DECRYPTION"
}
}
profile\_config = {
anti\_spyware = "BestPractice"
anti\_virus = "BestPractice"
vulnerability = "BestPractice"
file\_blocking = "BestPractice"
url\_filtering = "BestPractice"
}
}
}
|
map(object({
name = string
subnet\_group = string
vpc = string
description = optional(string, "Palo Alto Cloud NGFW")
security\_rules = map(any)
log\_profiles = map(any)
profile\_config = map(any)
}))
| `{}` | no | | [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `any` | n/a | yes | -| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `vpc`: key of VPC
- `vpc_subnet`: key of the VPC and subnet connected by '-' character
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `to_vpc_subnets`: subnets to which traffic from IGW is routed to the GWLB endpoint
- `delay`: number of seconds between adding endpoint to routing table
- `cloudngfw`: key of the cloudngfw correspond with the endpoints

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
vpc = "security\_vpc"
vpc\_subnet = "security\_vpc-gwlbe\_eastwest"
act\_as\_next\_hop = false
to\_vpc\_subnets = null
delay = 60
cloudngfw = "cloudngfw"
}
}
|
map(object({
name = string
vpc = string
vpc\_subnet = string
act\_as\_next\_hop = bool
to\_vpc\_subnets = string
delay = number
cloudngfw = string
}))
| `{}` | no | +| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `custom_names`: Optional map of names of the VPC Endpoints, used to override the default naming generated from the input `name`.
Each key is the Availability Zone identifier, for example `us-east-1b`.
- `gwlb`: key of GWLB. Required when GWLB Endpoint must connect to GWLB's service name
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint
- `cloudngfw_key`(optional): Key of the Cloud NGFW. Required when GWLB Endpoint must connect to Cloud NGFW's service name

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
custom\_names = optional(map(string), {})
gwlb = optional(string)
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
delay = optional(number, 0)
tags = optional(map(string))
cloudngfw\_key = optional(string)
}))
| `{}` | no | | [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | n/a | yes | -| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `name`: name of NAT Gateway
- `vpc_subnet`: key of the VPC and subnet connected by '-' character

Example:
natgws = {
security\_nat\_gw = {
name = "natgw"
vpc\_subnet = "security\_vpc-natgw"
}
}
|
map(object({
name = string
vpc\_subnet = string
}))
| `{}` | no | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | | [provider\_account](#input\_provider\_account) | The AWS Account where the resources should be deployed. | `string` | n/a | yes | | [provider\_role](#input\_provider\_role) | The predifined AWS assumed role for CloudNGFW. | `string` | n/a | yes | | [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | -| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `vpc_subnet`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = any
vms = list(string)
vpc = string
vpc\_subnet = string
security\_groups = string
}))
| n/a | yes | -| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `vpc_subnet`: key of the VPC and subnet connected by '-' character
- `vms`: keys of spoke VMs

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc\_subnet = "app1\_vpc-app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
vpc\_subnet = string
vms = list(string)
}))
| `{}` | no | -| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `vpc`: name of the VPC (needs to be one of the keys in map `vpcs`)
- `vpc_subnet`: key of the VPC and subnet connected by '-' character
- `security_group`: security group assigned to ENI used by VM
- `type`: EC2 type VM

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
vpc\_subnet = "app1\_vpc-app1\_vm"
security\_group = "app1\_vm"
type = "t3.micro"
}
}
|
map(object({
az = string
vpc = string
vpc\_subnet = string
security\_group = string
type = string
}))
| `{}` | no | -| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | -| [vpcs](#input\_vpcs) | A 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 }
"10.104.128.0/24" = { az = "eu-central-1b", 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 | +| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = map(object({
protocol = optional(string, "HTTP")
port = optional(number, 80)
health\_check\_port = optional(string, "80")
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
health\_check\_interval = optional(number, 10)
listener\_rules = map(object({
target\_protocol = string
target\_port = number
path\_pattern = list(string)
}))
}))
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| `{}` | no | +| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `name`: Name of the NLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs
- `internal_lb`(optional): flag to switch between internet\_facing and internal NLB
- `balance_rules` (optional): Rules defining the method of traffic balancing

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
vms = list(string)
internal\_lb = optional(bool, false)
balance\_rules = map(object({
protocol = string
port = string
stickiness = optional(bool, true)
}))
}))
| `{}` | no | +| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 VM type

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t2.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = optional(string, "t3.micro")
}))
| `{}` | no | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | `""` | no | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | ### Outputs diff --git a/products/terraform/docs/swfw/aws/vmseries/examples/panorama_standalone.md b/products/terraform/docs/swfw/aws/vmseries/examples/panorama_standalone.md index 5cccea735..69b347f46 100644 --- a/products/terraform/docs/swfw/aws/vmseries/examples/panorama_standalone.md +++ b/products/terraform/docs/swfw/aws/vmseries/examples/panorama_standalone.md @@ -50,7 +50,7 @@ Example was prepared for PAN-OS in **10.2.3** version as described in [AWS Deplo 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` +5. Review `terraform.tfvars` file, especially with lines commented by ` # TODO: update here`. To deploy Panorama with NAT Gateway for outbound access, please refer to the `# NAT GW` comments in the file. 6. Initialize Terraform: `terraform init` 7. Prepare plan: `terraform plan` 8. Deploy infrastructure: `terraform apply -auto-approve` @@ -90,6 +90,7 @@ Use a web browser to access https://x.x.x.x and login with admin and your previo | Name | Source | Version | |------|--------|---------| +| [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | | [panorama](#module\_panorama) | ../../modules/panorama | n/a | | [subnet\_sets](#module\_subnet\_sets) | ../../modules/subnet_set | n/a | | [vpc](#module\_vpc) | ../../modules/vpc | n/a | @@ -111,10 +112,11 @@ Use a web browser to access https://x.x.x.x and login with admin and your previo |------|-------------|------|---------|:--------:| | [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `map(any)` | `{}` | no | | [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | `""` | no | -| [panoramas](#input\_panoramas) | A 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 | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | +| [panoramas](#input\_panoramas) | A 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({
name = optional(string)
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
force\_detach = optional(bool, false)
skip\_destroy = optional(bool, false)
}))
encrypted = bool
kms\_key\_alias = optional(string, "alias/aws/ebs")
})

product\_code = optional(string, "eclz7j04vu9lf8ont8ta3n17o")
include\_deprecated\_ami = optional(bool, false)
panorama\_ami\_id = optional(string)
instance\_type = optional(string, "c5.4xlarge")
enable\_monitoring = optional(bool, false)
eip\_domain = optional(string, "vpc")

iam = object({
create\_role = bool
role\_name = string
})

enable\_imdsv2 = optional(bool, false)
}))
| `{}` | no | | [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | -| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | -| [vpcs](#input\_vpcs) | A 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 | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | `""` | no | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | ### Outputs diff --git a/products/terraform/docs/swfw/aws/vmseries/modules/alb.md b/products/terraform/docs/swfw/aws/vmseries/modules/alb.md index f5374da72..773c94d25 100644 --- a/products/terraform/docs/swfw/aws/vmseries/modules/alb.md +++ b/products/terraform/docs/swfw/aws/vmseries/modules/alb.md @@ -145,7 +145,7 @@ No modules. | [enable\_cross\_zone\_load\_balancing](#input\_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](#input\_idle\_timeout) | The time in seconds that the connection to the Load Balancer can be idle. | `number` | `60` | no | | [lb\_name](#input\_lb\_name) | Name of the Load Balancer to be created. | `string` | n/a | yes | -| [rules](#input\_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:
rules = {
"application\_name" = {
protocol = "communication protocol, since this is an ALB module accepted values are `HTTP` or `HTTPS`"
port = "communication port, defaults to protocol's default port"

certificate\_arn = "(HTTPS ONLY) this is the arn of an existing certificate, this module will not create one for you"
ssl\_policy = "(HTTPS ONLY) name of an ssl policy used by the Load Balancer's listener, defaults to AWS default, for available options see [AWS documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies)"

health\_check\_protocol = "this can be either `HTTP` or `HTTPS`, defaults to communication protocol"
health\_check\_port = "port used by the target group health check, if omitted, `traffic-port` will be used (which will be the same as communication port)"
health\_check\_healthy\_threshold = "number of consecutive health checks before considering target healthy, defaults to 3"
health\_check\_unhealthy\_threshold = "number of consecutive health checks before considering target unhealthy, defaults to 3"
health\_check\_interval = "time between each health check, between 5 and 300 seconds, defaults to 30s"
health\_check\_timeout = "health check probe timeout, defaults to AWS default value"
health\_check\_matcher = "response codes expected during health check, defaults to `200`"
health\_check\_path = "destination used by the health check request, defaults to `/`"

listener\_rules = "a map of rules for a listener created for this application, see `listener\_rules` block below for more information
}
}
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](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule#condition-blocks).

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:
listener\_rules = {
"rule\_priority" = { # string representation of a rule's priority (number from 1 - 50000)
target\_port = "port on which the target is listening for requests"
target\_protocol = "target protocol, can be `HTTP` or `HTTPS`"
protocol\_version = "one of `HTTP1`, `HTTP/2` or `GRPC`, defaults to `HTTP1`"

round\_robin = "bool, if set to true (default) the `round-robin` load balancing algorithm is used, otherwise a target attachment with least outstanding requests is chosen.

host\_headers = "a list of possible host headers, case insensitive, wildcards (`*`,`?`) are supported"
http\_headers = "a map of key-value pairs, where key is a name of an HTTP header and value is a list of possible values, same rules apply like for `host\_headers`"
http\_request\_method = "a list of possible HTTP request methods, case sensitive (upper case only), strict matching (no wildcards)"
path\_pattern = "a list of path patterns (w/o query strings), case sensitive, wildcards supported"
query\_strings = "a map of key-value pairs, key is a query string key pattern and value is a query string value pattern, case insensitive, wildcards supported, it is possible to match only a value pattern (the key value should be prefixed with `nokey\_`)"
source\_ip = "a list of source IP CDIR notation to match"
}
}


EXAMPLE
listener\_rules = {
"1" = {
target\_port = 8080
target\_protocol = "HTTP"
host\_headers = ["public-alb-1050443040.eu-west-1.elb.amazonaws.com"]
http\_headers = {
"X-Forwarded-For" = ["192.168.1.*"]
}
http\_request\_method = ["GET"]
}
"99" = {
host\_headers = ["www.else.org"]
target\_port = 8081
target\_protocol = "HTTP"
path\_pattern = ["/", "/login.php"]
query\_strings = {
"lang" = "us"
"nokey\_1" = "test"
}
source\_ip = ["10.0.0.0/8"]
}
}
| `any` | n/a | yes | +| [rules](#input\_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:
rules = {
"application\_name" = {
protocol = "communication protocol, since this is an ALB module accepted values are `HTTP` or `HTTPS`"
port = "communication port, defaults to protocol's default port"

certificate\_arn = "(HTTPS ONLY) this is the arn of an existing certificate, this module will not create one for you"
ssl\_policy = "(HTTPS ONLY) name of an ssl policy used by the Load Balancer's listener, defaults to AWS default, for available options see [AWS documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies)"

health\_check\_protocol = "this can be either `HTTP` or `HTTPS`, defaults to communication protocol"
health\_check\_port = "port used by the target group health check, if omitted, `traffic-port` will be used (which will be the same as communication port)"
health\_check\_healthy\_threshold = "number of consecutive health checks before considering target healthy, defaults to 3"
health\_check\_unhealthy\_threshold = "number of consecutive health checks before considering target unhealthy, defaults to 3"
health\_check\_interval = "time between each health check, between 5 and 300 seconds, defaults to 30s"
health\_check\_timeout = "health check probe timeout, defaults to AWS default value"
health\_check\_matcher = "response codes expected during health check, defaults to `200`"
health\_check\_path = "destination used by the health check request, defaults to `/`"

listener\_rules = "a map of rules for a listener created for this application, see `listener\_rules` block below for more information
}
}
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](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule#condition-blocks).

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:
listener\_rules = {
"rule\_priority" = { # string representation of a rule's priority (number from 1 - 50000)
target\_port = "port on which the target is listening for requests"
target\_protocol = "target protocol, can be `HTTP` or `HTTPS`"
protocol\_version = "one of `HTTP1`, `HTTP/2` or `GRPC`, defaults to `HTTP1`"

round\_robin = "bool, if set to true (default) the `round-robin` load balancing algorithm is used, otherwise a target attachment with least outstanding requests is chosen.

host\_headers = "a list of possible host headers, case insensitive, wildcards (`*`,`?`) are supported"
http\_headers = "a map of key-value pairs, where key is a name of an HTTP header and value is a list of possible values, same rules apply like for `host\_headers`"
http\_request\_method = "a list of possible HTTP request methods, case sensitive (upper case only), strict matching (no wildcards)"
path\_pattern = "a list of path patterns (w/o query strings), case sensitive, wildcards supported"
query\_strings = "a map of key-value pairs, key is a query string key pattern and value is a query string value pattern, case insensitive, wildcards supported, it is possible to match only a value pattern (the key value should be prefixed with `nokey\_`)"
source\_ip = "a list of source IP CDIR notation to match"
}
}


EXAMPLE
listener\_rules = {
"1" = {
target\_port = 8080
target\_protocol = "HTTP"
host\_headers = ["public-alb-1050443040.eu-west-1.elb.amazonaws.com"]
http\_headers = {
"X-Forwarded-For" = ["192.168.1.*"]
}
http\_request\_method = ["GET"]
}
"99" = {
host\_headers = ["www.else.org"]
target\_port = 8081
target\_protocol = "HTTP"
path\_pattern = ["/", "/login.php"]
query\_strings = {
"lang" = "us"
"nokey\_1" = "test"
}
source\_ip = ["10.0.0.0/8"]
}
}
|
map(object({
protocol = string
port = number
certificate\_arn = optional(string)
ssl\_policy = optional(string)
health\_check\_protocol = optional(string)
health\_check\_port = optional(string)
health\_check\_healthy\_threshold = optional(number)
health\_check\_unhealthy\_threshold = optional(number)
health\_check\_interval = optional(number)
health\_check\_timeout = optional(number)
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
listener\_rules = map(object({
target\_port = number
target\_protocol = string
protocol\_version = optional(string)
round\_robin = optional(bool, true)
host\_headers = optional(list(string))
http\_headers = optional(map(string))
http\_request\_method = optional(list(string))
path\_pattern = optional(list(string))
query\_strings = optional(map(string))
source\_ip = optional(list(string))
}))
}))
| n/a | yes | | [security\_groups](#input\_security\_groups) | A list of security group IDs to use with a Load Balancer.

If security groups are created with a [VPC module](../vpc) you can use output from that module like this:
security\_groups              = [module.vpc.security\_group\_ids["load\_balancer\_security\_group"]]
For more information on the `load_balancer_security_group` key refer to the [VPC module documentation](../vpc). | `list(string)` | n/a | yes | | [subnets](#input\_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 attribute
`id` identifying AWS subnet.

Examples:

You can define the values directly:
subnets = {
"us-east-1a" = { id = "snet-123007" }
"us-east-1b" = { id = "snet-123008" }
}
You can also use output from the `subnet_sets` module:
subnets        = { for k, v in module.subnet\_sets["untrust"].subnets : k => { id = v.id } }
|
map(object({
id = string
}))
| n/a | yes | | [tags](#input\_tags) | Map of AWS tags to apply to all the created resources. | `map(string)` | `{}` | no | diff --git a/products/terraform/docs/swfw/aws/vmseries/modules/asg.md b/products/terraform/docs/swfw/aws/vmseries/modules/asg.md index 6f836eb9c..ea1db5d82 100644 --- a/products/terraform/docs/swfw/aws/vmseries/modules/asg.md +++ b/products/terraform/docs/swfw/aws/vmseries/modules/asg.md @@ -81,6 +81,9 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [airs\_deployment](#input\_airs\_deployment) | Deployment type VM-Series (False) or AI Runtime Security (True) | `bool` | `false` | no | +| [airs\_instance\_type](#input\_airs\_instance\_type) | EC2 instance type. | `string` | `"c6in.xlarge"` | no | +| [airs\_product\_code](#input\_airs\_product\_code) | Product code corresponding to a chosen AIRS license type model - by default - BYOL.
To check the available license type models and their codes, please refer to the | `string` | `"b261y39exndwe1ltro1tqpeog"` | no | | [asg\_name](#input\_asg\_name) | Name of the autoscaling group to create | `string` | `"asg"` | no | | [bootstrap\_options](#input\_bootstrap\_options) | Bootstrap options to put into userdata | `any` | `{}` | no | | [delete\_timeout](#input\_delete\_timeout) | Timeout needed to correctly drain autoscaling group while deleting ASG.

By default in AWS timeout is set to 10 minutes, which is too low and causes issue:
Error: waiting for Auto Scaling Group (example-asg) drain: timeout while waiting for state to become '0' (last state: '1', timeout: 10m0s) | `string` | `"20m"` | no | @@ -88,23 +91,23 @@ No modules. | [delicense\_ssm\_param\_name](#input\_delicense\_ssm\_param\_name) | Secure string in Parameter Store with value in below format:
{"username":"ACCOUNT","password":"PASSWORD","panorama1":"IP\_ADDRESS1","panorama2":"IP\_ADDRESS2","license\_manager":"LICENSE\_MANAGER\_NAME"}"
the format can either be the plain name in case you store it without hierarchy or with a "/" in case you store in in a hierarchy | `any` | `null` | no | | [desired\_capacity](#input\_desired\_capacity) | Number of Amazon EC2 instances that should be running in the group. | `number` | `2` | no | | [ebs\_kms\_id](#input\_ebs\_kms\_id) | Alias for AWS KMS used for EBS encryption in VM-Series | `string` | `"alias/aws/ebs"` | no | -| [enabled_metrics](#input_enabled_metrics) | List of Auto Scaling group metrics to collect. Set to an empty list to disable metrics collection. | `list(string)` |
[
"GroupMinSize",
"GroupMaxSize",
"GroupDesiredCapacity",
"GroupInServiceInstances",
"GroupPendingInstances",
"GroupStandbyInstances",
"GroupTerminatingInstances",
"GroupTotalInstances",
"WarmPoolDesiredCapacity",
"WarmPoolWarmedCapacity",
"WarmPoolPendingCapacity",
"WarmPoolTerminatingCapacity",
"WarmPoolTotalCapacity",
"GroupAndWarmPoolDesiredCapacity",
"GroupAndWarmPoolTotalCapacity",
]
| no | +| [enabled\_metrics](#input\_enabled\_metrics) | List of Auto Scaling group metrics to collect. Set to an empty list to disable metrics collection. | `list(string)` |
[
"GroupMinSize",
"GroupMaxSize",
"GroupDesiredCapacity",
"GroupInServiceInstances",
"GroupPendingInstances",
"GroupStandbyInstances",
"GroupTerminatingInstances",
"GroupTotalInstances",
"WarmPoolDesiredCapacity",
"WarmPoolWarmedCapacity",
"WarmPoolPendingCapacity",
"WarmPoolTerminatingCapacity",
"WarmPoolTotalCapacity",
"GroupAndWarmPoolDesiredCapacity",
"GroupAndWarmPoolTotalCapacity"
]
| no | | [fw\_license\_type](#input\_fw\_license\_type) | Select License type (byol/payg1/payg2) | `string` | `"byol"` | no | | [global\_tags](#input\_global\_tags) | Map of AWS tags to apply to all the created resources. | `map(any)` | n/a | yes | | [health\_check](#input\_health\_check) | Controls how health checking is done. |
object({
grace\_period = number
type = string
})
|
{
"grace\_period": 300,
"type": "EC2"
}
| no | | [include\_deprecated\_ami](#input\_include\_deprecated\_ami) | In certain scenarios, customers may deploy a VM-Series instance through the marketplace,
only to later discover that the ami has been deprecated, resulting in pipeline failures.
Setting the specified parameter to `true` will enable the continued use of deprecated AMIs,
mitigating this issue. | `bool` | `false` | no | | [instance\_refresh](#input\_instance\_refresh) | If this variable is configured (not null), then start an Instance Refresh when Auto Scaling Group is updated.

Instance refresh is defined by attributes:
- `strategy` - Strategy to use for instance refresh. The only allowed value is Rolling
- `preferences` - Override default parameters for Instance Refresh:
- `checkpoint_delay` - Number of seconds to wait after a checkpoint. Defaults to 3600.
- `checkpoint_percentages` - List of percentages for each checkpoint. Values must be unique and in ascending order.
To replace all instances, the final number must be 100.
- `instance_warmup` - Number of seconds until a newly launched instance is configured and ready to use.
Default behavior is to use the Auto Scaling Group's health check grace period.
- `min_healthy_percentage` - Amount of capacity in the Auto Scaling group that must remain healthy during an instance refresh
to allow the operation to continue, as a percentage of the desired capacity of the Auto Scaling group.
Defaults to 90.
- `skip_matching` - Replace instances that already have your desired configuration. Defaults to false.
- `auto_rollback` - Automatically rollback if instance refresh fails. Defaults to false.
This option may only be set to true when specifying a launch\_template or mixed\_instances\_policy.
- `scale_in_protected_instances` - Behavior when encountering instances protected from scale in are found.
Available behaviors are Refresh, Ignore, and Wait. Default is Ignore.
- `standby_instances` - Behavior when encountering instances in the Standby state in are found.
Available behaviors are Terminate, Ignore, and Wait. Default is Ignore.
- `trigger` - Set of additional property names that will trigger an Instance Refresh.
A refresh will always be triggered by a change in any of launch\_configuration, launch\_template, or mixed\_instances\_policy. |
object({
strategy = string
preferences = object({
checkpoint\_delay = number
checkpoint\_percentages = list(number)
instance\_warmup = number
min\_healthy\_percentage = number
skip\_matching = bool
auto\_rollback = bool
scale\_in\_protected\_instances = string
standby\_instances = string
})
triggers = list(string)
})
| `null` | no | | [instance\_type](#input\_instance\_type) | EC2 instance type. | `string` | `"m5.xlarge"` | no | -| [interfaces](#input\_interfaces) | Map of the network interface specifications.
If "mgmt-interface-swap" bootstrap option is enabled, ensure dataplane interface `device_index` is set to 0 and the firewall management interface `device_index` is set to 1.
Available options:
- `device_index` = (Required\|int) Determines order in which interfaces are attached to the instance. Interface with `0` is attached at boot time.
- `subnet_id` = (Required\|string) Subnet ID to create the ENI in.
- `name` = (Optional\|string) Name tag for the ENI. Defaults to instance name suffixed by map's key.
- `description` = (Optional\|string) A descriptive name for the ENI.
- `create_public_ip` = (Optional\|bool) Whether to create a public IP for the ENI. Defaults to false.
- `eip_allocation_id` = (Optional\|string) Associate an existing EIP to the ENI.
- `private_ips` = (Optional\|list) List of private IPs to assign to the ENI. If not set, dynamic allocation is used.
- `public_ipv4_pool` = (Optional\|string) EC2 IPv4 address pool identifier.
- `source_dest_check` = (Optional\|bool) Whether to enable source destination checking for the ENI. Defaults to false.
- `security_group_ids` = (Optional\|list) A list of Security Group IDs to assign to this interface. Defaults to null.

Example:
interfaces = {
mgmt = {
device\_index = 0
subnet\_id = aws\_subnet.mgmt.id
name = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
security\_group\_ids = ["sg-123456"]
},
public = {
device\_index = 1
subnet\_id = aws\_subnet.public.id
name = "public"
create\_public\_ip = true
},
private = {
device\_index = 2
subnet\_id = aws\_subnet.private.id
name = "private"
},
]
| `map(any)` | n/a | yes | +| [interfaces](#input\_interfaces) | Map of the network interface specifications.
If "mgmt-interface-swap" bootstrap option is enabled, ensure dataplane interface `device_index` is set to 0 and the firewall management interface `device_index` is set to 1.
Available options:
- `device_index` = (Required\|int) Determines order in which interfaces are attached to the instance. Interface with `0` is attached at boot time.
- `subnet_id` = (Required\|string) Subnet ID to create the ENI in.
- `name` = (Optional\|string) Name tag for the ENI. Defaults to instance name suffixed by map's key.
- `description` = (Optional\|string) A descriptive name for the ENI.
- `create_public_ip` = (Optional\|bool) Whether to create a public IP for the ENI. Defaults to false.
- `eip_allocation_id` = (Optional\|string) Associate an existing EIP to the ENI.
- `private_ips` = (Optional\|list) List of private IPs to assign to the ENI. If not set, dynamic allocation is used.
- `public_ipv4_pool` = (Optional\|string) EC2 IPv4 address pool identifier.
- `source_dest_check` = (Optional\|bool) Whether to enable source destination checking for the ENI. Defaults to false.
- `security_group_ids` = (Optional\|list) A list of Security Group IDs to assign to this interface. Defaults to null.

Example:
interfaces = {
mgmt = {
device\_index = 0
subnet\_id = aws\_subnet.mgmt.id
name = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
security\_group\_ids = ["sg-123456"]
},
public = {
device\_index = 1
subnet\_id = aws\_subnet.public.id
name = "public"
create\_public\_ip = true
},
private = {
device\_index = 2
subnet\_id = aws\_subnet.private.id
name = "private"
},
]
|
map(object({
device\_index = number
subnet\_id = map(string)
name = optional(string)
description = optional(string)
create\_public\_ip = optional(bool, false)
eip\_allocation\_id = optional(string)
private\_ips = optional(list(string))
ipv6\_address\_count = optional(number, null)
public\_ipv4\_pool = optional(string)
source\_dest\_check = optional(bool, false)
security\_group\_ids = optional(list(string), null)
}))
| n/a | yes | | [ip\_target\_groups](#input\_ip\_target\_groups) | Target groups (type IP) for load balancers, which are used by Lamda to register VM-Series IP of untrust interface |
list(object({
arn = string
port = string
}))
| `[]` | no | -| [lambda\_execute\_pip\_install\_once](#input\_lambda\_execute\_pip\_install\_once) | Flag used in local-exec command installing Python packages required by Lambda.

If set to true, local-exec is executed only once, when all resources are created.
If you need to have idempotent behaviour for terraform apply every time and you have downloaded
all required Python packages, set it to true.

If set to false, every time it's checked if files for package pan\_os\_python are downloaded.
If not, it causes execution of local-exec command in two consecutive calls of terraform apply:
- first time value of installed-pan-os-python is changed from true (or empty) to false
- second time value of installed-pan-os-python is changed from false to true
In summary while executing code from scratch, two consecutive calls of terraform apply are not idempotent.
The third execution of terraform apply show no changes.
While using modules in CI/CD pipelines, when agents are selected randomly, set this value to false
in order to check every time, if pan\_os\_python package is downloaded. sdfdsf sdfvars | `bool` | `false` | no | +| [lambda\_execute\_pip\_install\_once](#input\_lambda\_execute\_pip\_install\_once) | Flag used in local-exec command installing Python packages required by Lambda.

If set to true, local-exec is executed only once, when all resources are created.
If you need to have idempotent behaviour for terraform apply every time and you have downloaded
all required Python packages, set it to true.

If set to false, every time it's checked if files for package pan\_os\_python are downloaded.
If not, it causes execution of local-exec command in two consecutive calls of terraform apply:
- first time value of installed-pan-os-python is changed from true (or empty) to false
- second time value of installed-pan-os-python is changed from false to true
In summary while executing code from scratch, two consecutive calls of terraform apply are not idempotent.
The third execution of terraform apply show no changes.
While using modules in CI/CD pipelines, when agents are selected randomly, set this value to false
in order to check every time, if pan\_os\_python package is downloaded. | `bool` | `false` | no | | [lambda\_timeout](#input\_lambda\_timeout) | Amount of time Lambda Function has to run in seconds. | `number` | `30` | no | | [launch\_template\_update\_default\_version](#input\_launch\_template\_update\_default\_version) | Whether to update launch template default version each update.

If set to true, every time when e.g. bootstrap options are changed, new version is created and default version is updated.
If set to false, every time when e.g. bootstrap options are changed, new version is created, but default version is not changed. | `bool` | `true` | no | | [launch\_template\_version](#input\_launch\_template\_version) | Launch template version to use to launch instances | `string` | `"$Latest"` | no | | [lifecycle\_hook\_timeout](#input\_lifecycle\_hook\_timeout) | How long should we wait for lambda to finish | `number` | `300` | no | | [max\_size](#input\_max\_size) | Maximum size of the Auto Scaling Group. | `number` | `2` | no | +| [metrics\_granularity](#input\_metrics\_granularity) | Granularity for Auto Scaling group metrics. | `string` | `"1Minute"` | no | | [min\_size](#input\_min\_size) | Minimum size of the Auto Scaling Group. | `number` | `1` | no | -| [metrics_granularity](#input_metrics_granularity) | Granularity for Auto Scaling group metrics. | `string` | `"1Minute"` | no | | [name\_prefix](#input\_name\_prefix) | All resource names will be prepended with this string | `string` | n/a | yes | | [region](#input\_region) | AWS region | `string` | n/a | yes | | [reserved\_concurrent\_executions](#input\_reserved\_concurrent\_executions) | Amount of reserved concurrent execussions for lambda function. | `number` | `100` | no | @@ -124,7 +127,7 @@ No modules. | [vmseries\_ami\_id](#input\_vmseries\_ami\_id) | The AMI from which to launch the instance. Takes precedence over fw\_version and fw\_license\_type | `string` | `null` | no | | [vmseries\_iam\_instance\_profile](#input\_vmseries\_iam\_instance\_profile) | IAM instance profile used in launch template | `string` | `""` | no | | [vmseries\_product\_code](#input\_vmseries\_product\_code) | Product code corresponding to a chosen VM-Series license type model - by default - BYOL.
To check the available license type models and their codes, please refer to the
[VM-Series documentation](https://docs.paloaltonetworks.com/vm-series/10-0/vm-series-deployment/set-up-the-vm-series-firewall-on-aws/deploy-the-vm-series-firewall-on-aws/obtain-the-ami/get-amazon-machine-image-ids.html) | `string` | `"6njl1pau431dv1qxipg63mvah"` | no | -| [vmseries\_version](#input\_vmseries\_version) | Select which FW version to deploy | `string` | `"10.2.9-h1"` | no | +| [vmseries\_version](#input\_vmseries\_version) | VM-Series Firewall/AIRS version to deploy.
To list all available VM-Series versions, run the command provided below.
Please have in mind that the `product-code` may need to be updated - check the `vmseries_product_code` variable for more information.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=6njl1pau431dv1qxipg63mvah" "Name=name,Values=PA-VM-AWS*" --output json --query "Images[].Description" \| grep -o 'PA-VM-AWS-.\*' \| sort
To list all available AIRS versions, run the command provided below.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=b261y39exndwe1ltro1tqpeog" "Name=name,Values=PA-AI-Runtime-Security-AWS-\*" --output json --query "Images[].Name" \| grep -o 'PA-AI-Runtime-Security-AWS-.*' \| sort
| `string` | `"11.1.4-h7"` | no | ### Outputs diff --git a/products/terraform/docs/swfw/aws/vmseries/modules/bootstrap.md b/products/terraform/docs/swfw/aws/vmseries/modules/bootstrap.md index b8abc37de..28e8f57a3 100644 --- a/products/terraform/docs/swfw/aws/vmseries/modules/bootstrap.md +++ b/products/terraform/docs/swfw/aws/vmseries/modules/bootstrap.md @@ -134,7 +134,7 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [bootstrap\_directories](#input\_bootstrap\_directories) | List of subdirectories to be created inside the bucket (whether or not they exist locally inside the `source_root_directory`). A hardcoded pan-os requirement. | `list(string)` |
[
"config/",
"content/",
"software/",
"license/",
"plugins/"
]
| no | -| [bootstrap\_options](#input\_bootstrap\_options) | Object define bootstrap options used in the init-cfg.txt file.

There are available bootstrap parameters:
- `hostname` - (`string`, optional) The hostname of the VM-series instance.
- `panorama-server` - (`string`, optional) The FQDN or IP address of the primary Panorama server.
- `panorama-server-2` - (`string`, optional) The FQDN or IP address of the secondary Panorama server.
- `tplname` - (`string`, optional) The Panorama template stack name.
- `dgname` - (`string`, optional) The Panorama device group name.
- `cgname` - (`string`, optional) The Panorama collector group name.
- `dns-primary` - (`string`, optional) The IP address of the primary DNS server.
- `dns-secondary` - (`string`, optional) The IP address of the secondary DNS server.
- `auth-key` - (`string`, optional) VM-Series authentication key generated via plugin sw\_fw\_license.
- `vm-auth-key` - (`string`, optional) VM-Series authentication key generated on Panorama.
- `op-command-modes` - (`string`, optional) Set jumbo-frame and/or mgmt-interface-swap.
- `plugin-op-commands` - (`string`, optional) Set plugin-op-commands.
- `dhcp-send-hostname` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall sends its hostname to the DHCP server.
- `dhcp-send-client-id` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall sends its client ID to the DHCP server.
- `dhcp-accept-server-hostname` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall accepts its hostname from the DHCP server.
- `dhcp-accept-server-domain` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall accepts its DNS server from the DHCP server. | `any` |
{
"dhcp-accept-server-domain": "yes",
"dhcp-accept-server-hostname": "yes",
"dhcp-send-client-id": "yes",
"dhcp-send-hostname": "yes"
}
| no | +| [bootstrap\_options](#input\_bootstrap\_options) | Object define bootstrap options used in the init-cfg.txt file.

There are available bootstrap parameters:
- `hostname` - (`string`, optional) The hostname of the VM-series instance.
- `mgmt-interface-swap` - (`string`, optional) Allows to swap the management interface with the dataplane interface eth1/1.
- `panorama-server` - (`string`, optional) The FQDN or IP address of the primary Panorama server.
- `panorama-server-2` - (`string`, optional) The FQDN or IP address of the secondary Panorama server.
- `tplname` - (`string`, optional) The Panorama template stack name.
- `dgname` - (`string`, optional) The Panorama device group name.
- `cgname` - (`string`, optional) The Panorama collector group name.
- `dns-primary` - (`string`, optional) The IP address of the primary DNS server.
- `dns-secondary` - (`string`, optional) The IP address of the secondary DNS server.
- `auth-key` - (`string`, optional) VM-Series authentication key generated via plugin sw\_fw\_license.
- `vm-auth-key` - (`string`, optional) VM-Series authentication key generated on Panorama.
- `op-command-modes` - (`string`, optional) Set jumbo-frame and/or mgmt-interface-swap.
- `plugin-op-commands` - (`string`, optional) Set plugin-op-commands.
- `dhcp-send-hostname` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall sends its hostname to the DHCP server.
- `dhcp-send-client-id` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall sends its client ID to the DHCP server.
- `dhcp-accept-server-hostname` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall accepts its hostname from the DHCP server.
- `dhcp-accept-server-domain` - (`string`, optional) The DHCP server determines a value of yes or no. If yes, the firewall accepts its DNS server from the DHCP server.
- `authcodes` - (`string`, optional) The authcode use to register the VM-Series firewall.
- `vm-series-auto-registration-pin-id` - (`string`, optional) The VM-Series registration PIN ID for installing the device certificate on the VM-Series firewall.
- `vm-series-auto-registration-pin-value` - (`string`, optional) The VM-Series registration PIN Value for installing the device certificate on the VM-Series firewall. |
object({
hostname = optional(string)
mgmt-interface-swap = optional(string)
panorama-server = optional(string)
panorama-server-2 = optional(string)
tplname = optional(string)
dgname = optional(string)
cgname = optional(string)
dns-primary = optional(string)
dns-secondary = optional(string)
auth-key = optional(string)
vm-auth-key = optional(string)
op-command-modes = optional(string)
plugin-op-commands = optional(string)
dhcp-send-hostname = optional(string)
dhcp-send-client-id = optional(string)
dhcp-accept-server-hostname = optional(string)
dhcp-accept-server-domain = optional(string)
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})
| n/a | yes | | [bucket\_name](#input\_bucket\_name) | Name of a bucket to reuse or create (depending on `create_bucket` value). In the latter case - if empty, the name will be auto-generated. | `string` | `""` | no | | [create\_bucket](#input\_create\_bucket) | If true, a new bucket will be created. When false, name of existing bucket to use has to be provided in `bucket_name` variable. | `bool` | `true` | no | | [create\_iam\_role\_policy](#input\_create\_iam\_role\_policy) | If true, a new IAM role with policy will be created. When false, name of existing IAM role to use has to be provided in `iam_role_name` variable. | `bool` | `true` | no | diff --git a/products/terraform/docs/swfw/aws/vmseries/modules/cloudngfw.md b/products/terraform/docs/swfw/aws/vmseries/modules/cloudngfw.md index 871320652..bb94ae62f 100644 --- a/products/terraform/docs/swfw/aws/vmseries/modules/cloudngfw.md +++ b/products/terraform/docs/swfw/aws/vmseries/modules/cloudngfw.md @@ -37,14 +37,14 @@ For example usage, please refer to the [examples](https://github.com/PaloAltoNet |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.0, < 2.0.0 | | [aws](#requirement\_aws) | ~> 5.17 | -| [cloudngfwaws](#requirement\_cloudngfwaws) | 2.0.6 | +| [cloudngfwaws](#requirement\_cloudngfwaws) | 2.0.20 | ### Providers | Name | Version | |------|---------| | [aws](#provider\_aws) | ~> 5.17 | -| [cloudngfwaws](#provider\_cloudngfwaws) | 2.0.6 | +| [cloudngfwaws](#provider\_cloudngfwaws) | 2.0.20 | ### Modules @@ -56,11 +56,11 @@ No modules. |------|------| | [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | | [aws_cloudwatch_log_stream.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_stream) | resource | -| [cloudngfwaws_commit_rulestack.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.6/docs/resources/commit_rulestack) | resource | -| [cloudngfwaws_ngfw.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.6/docs/resources/ngfw) | resource | -| [cloudngfwaws_ngfw_log_profile.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.6/docs/resources/ngfw_log_profile) | resource | -| [cloudngfwaws_rulestack.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.6/docs/resources/rulestack) | resource | -| [cloudngfwaws_security_rule.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.6/docs/resources/security_rule) | resource | +| [cloudngfwaws_commit_rulestack.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.20/docs/resources/commit_rulestack) | resource | +| [cloudngfwaws_ngfw.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.20/docs/resources/ngfw) | resource | +| [cloudngfwaws_ngfw_log_profile.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.20/docs/resources/ngfw_log_profile) | resource | +| [cloudngfwaws_rulestack.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.20/docs/resources/rulestack) | resource | +| [cloudngfwaws_security_rule.this](https://registry.terraform.io/providers/PaloAltoNetworks/cloudngfwaws/2.0.20/docs/resources/security_rule) | resource | | [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | ### Inputs @@ -70,13 +70,13 @@ No modules. | [description](#input\_description) | Cloud NGFW description. | `string` | `"CloudNGFW"` | no | | [description\_rule](#input\_description\_rule) | The rulestack description. | `string` | `"CloudNGFW rulestack"` | no | | [endpoint\_mode](#input\_endpoint\_mode) | The endpoint mode indicate the creation method of endpoint for target VPC. Customer Managed required to create endpoint manually. | `string` | `"CustomerManaged"` | no | -| [log\_profiles](#input\_log\_profiles) | The CloudWatch logs group name should correspond with the assumed role generated in cfn.
- `create_cw` = (Required\|string) Whether to create AWS CloudWatch log group.
- `name` = (Required\|string) The CW log group should correspond with cfn cross zone role.
- `destination_type` = (Required\|string) Only supported type is "CloudWatchLogs".
- `log_type` = (Required\|string) The firewall log type.
Example:
log\_profiles = {
dest\_1 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "THREAT"
}
dest\_2 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "TRAFFIC"
}
dest\_3 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "DECRYPTION"
}
}
|
map(object({
create\_cw = bool
name = string
destination\_type = string
log\_type = string
}
))
| `{}` | no | +| [log\_profiles](#input\_log\_profiles) | The CloudWatch logs group name should correspond with the assumed role generated in cfn.
- `create_cw` = (Optional\|string) Whether to create AWS CloudWatch log group.
- `name` = (Required\|string) The CW log group should correspond with cfn cross zone role.
- `destination_type` = (Required\|string) Only supported type is "CloudWatchLogs".
- `log_type` = (Required\|string) The firewall log type.
Example:
log\_profiles = {
dest\_1 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "THREAT"
}
dest\_2 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "TRAFFIC"
}
dest\_3 = {
create\_cw = true
name = "PaloAltoCloudNGFW"
destination\_type = "CloudWatchLogs"
log\_type = "DECRYPTION"
}
}
|
map(object({
create\_cw = optional(bool, false)
name = string
destination\_type = string
log\_type = string
}
))
| `{}` | no | | [name](#input\_name) | Name of the Cloud NGFW instance. | `string` | n/a | yes | | [profile\_config](#input\_profile\_config) | The rulestack profile config. | `map(any)` | `{}` | no | | [retention\_in\_days](#input\_retention\_in\_days) | CloudWatch log groups retains logs. | `number` | `365` | no | | [rulestack\_name](#input\_rulestack\_name) | The rulestack name. | `string` | n/a | yes | | [rulestack\_scope](#input\_rulestack\_scope) | The rulestack scope. A local rulestack will require that you've retrieved a LRA JWT. A global rulestack will require that you've retrieved a GRA JWT | `string` | `"Local"` | no | -| [security\_rules](#input\_security\_rules) | Example:
security\_rules = {
rule\_1 = {
rule\_list = "LocalRule"
priority = 3
name = "tf-security-rule"
description = "Also configured by Terraform"
source\_cidrs = ["any"]
destination\_cidrs = ["0.0.0.0/0"]
negate\_destination = false
protocol = "application-default"
applications = ["any"]
category\_feeds = [""]
category\_url\_category\_names = [""]
action = "Allow"
logging = true
audit\_comment = "initial config"
}
}
|
map(object({
rule\_list = string
priority = number
name = string
description = string
source\_cidrs = set(string)
destination\_cidrs = set(string)
negate\_destination = bool
protocol = string
applications = set(string)
category\_feeds = set(string)
category\_url\_category\_names = set(string)
action = string
logging = bool
audit\_comment = string
}))
| `{}` | no | +| [security\_rules](#input\_security\_rules) | Example:
security\_rules = {
rule\_1 = {
rule\_list = "LocalRule"
priority = 3
name = "tf-security-rule"
description = "Also configured by Terraform"
source\_cidrs = ["any"]
destination\_cidrs = ["0.0.0.0/0"]
negate\_destination = false
protocol = "application-default"
applications = ["any"]
category\_feeds = [""]
category\_url\_category\_names = [""]
action = "Allow"
logging = true
audit\_comment = "initial config"
}
}
|
map(object({
rule\_list = string
priority = number
name = string
description = optional(string)
source\_cidrs = set(string)
destination\_cidrs = set(string)
negate\_destination = optional(bool, false)
protocol = optional(string, "application-default")
applications = optional(set(string), ["any"])
category\_feeds = optional(set(string))
category\_url\_category\_names = optional(set(string))
action = string
logging = bool
audit\_comment = optional(string)
}))
| `{}` | no | | [subnets](#input\_subnets) | Map of Subnets where to create the NAT Gateways. Each map's key is the availability zone name and each map's object has an attribute `id` identifying AWS Subnet. Importantly, the traffic returning from the NAT Gateway uses the Subnet's route table.
The keys of this input map are used for the output map `endpoints`.
Example for users of module `subnet_set`:
subnets = module.subnet\_set.subnets
Example:
subnets = {
"us-east-1a" = { id = "snet-123007" }
"us-east-1b" = { id = "snet-123008" }
}
|
map(object({
id = string
tags = map(string)
}))
| n/a | yes | | [tags](#input\_tags) | AWS Tags for the VPC Endpoints. | `map(string)` | `{}` | no | | [vpc\_id](#input\_vpc\_id) | ID of the security VPC the Load Balancer should be created in. | `string` | n/a | yes | diff --git a/products/terraform/docs/swfw/aws/vmseries/modules/nat_gateway_set.md b/products/terraform/docs/swfw/aws/vmseries/modules/nat_gateway_set.md index db0ebba57..cb8d86a2f 100644 --- a/products/terraform/docs/swfw/aws/vmseries/modules/nat_gateway_set.md +++ b/products/terraform/docs/swfw/aws/vmseries/modules/nat_gateway_set.md @@ -92,9 +92,9 @@ No modules. | [create\_nat\_gateway](#input\_create\_nat\_gateway) | If false, does not create a new NAT Gateway, but instead reads a pre-existing one. | `bool` | `true` | no | | [eip\_domain](#input\_eip\_domain) | Indicates if this EIP is for use in VPC | `string` | `"vpc"` | no | | [eip\_tags](#input\_eip\_tags) | n/a | `map(string)` | `{}` | no | -| [eips](#input\_eips) | Optional map of Elastic IP attributes. Each key is an Availability Zone name, for example "us-east-1b". Each entry has optional attributes `name`, `public_ip`, `id`.
These are mainly useful to select a pre-existing Elastic IP when create\_eip is false. Example:
eips = {
"us-east-1a" = { id = aws\_eip.a.id }
"us-east-1b" = { id = aws\_eip.b.id }
}
The `name` attribute can be used both for selecting the pre-existing Elastic IP, or for customizing a newly created Elastic IP:
eips = {
"us-east-1a" = { name = "Alice" }
"us-east-1b" = { name = "Bob" }
}
| `map` | `{}` | no | +| [eips](#input\_eips) | Optional map of Elastic IP attributes. Each key is an Availability Zone name, for example "us-east-1b". Each entry has optional attributes `name`, `public_ip`, `id`.
These are mainly useful to select a pre-existing Elastic IP when create\_eip is false. Example:
eips = {
"us-east-1a" = { id = aws\_eip.a.id }
"us-east-1b" = { id = aws\_eip.b.id }
}
The `name` attribute can be used both for selecting the pre-existing Elastic IP, or for customizing a newly created Elastic IP:
eips = {
"us-east-1a" = { name = "Alice" }
"us-east-1b" = { name = "Bob" }
}
|
map(object({
create\_eip = optional(bool, true)
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
}))
| `{}` | no | | [global\_tags](#input\_global\_tags) | n/a | `map(string)` | `{}` | no | -| [nat\_gateway\_names](#input\_nat\_gateway\_names) | A map, where each key is an Availability Zone name, for example "us-east-1b". Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
The name is kept in an AWS standard Name tag.
Example:
nat\_gateway\_names = {
"us-east-1a" = "example-natgwa"
"us-east-1b" = "example-natgwb"
}
| `map(string)` | `{}` | no | +| [nat\_gateway\_names](#input\_nat\_gateway\_names) | A map, where each key is an Availability Zone name, for example "us-east-1b". Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
The name is kept in an AWS standard Name tag.
Example:
nat\_gateway\_names = {
"us-east-1a" = "example-natgwa"
"us-east-1b" = "example-natgwb"
}
| `map(string)` | `{}` | no | | [nat\_gateway\_tags](#input\_nat\_gateway\_tags) | n/a | `map(string)` | `{}` | no | | [subnets](#input\_subnets) | Map of Subnets where to create the NAT Gateways. Each map's key is the availability zone name and each map's object has an attribute `id` identifying AWS Subnet. Importantly, the traffic returning from the NAT Gateway uses the Subnet's route table.
The keys of this input map are used for the output map `endpoints`.
Example for users of module `subnet_set`:
subnets = module.subnet\_set.subnets
Example:
subnets = {
"us-east-1a" = { id = "snet-123007" }
"us-east-1b" = { id = "snet-123008" }
}
|
map(object({
id = string
tags = map(string)
}))
| n/a | yes | diff --git a/products/terraform/docs/swfw/aws/vmseries/modules/nlb.md b/products/terraform/docs/swfw/aws/vmseries/modules/nlb.md index bbe9265df..457a0bec0 100644 --- a/products/terraform/docs/swfw/aws/vmseries/modules/nlb.md +++ b/products/terraform/docs/swfw/aws/vmseries/modules/nlb.md @@ -74,7 +74,7 @@ No modules. | [access\_logs\_byob](#input\_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](#input\_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](#input\_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 | -| [balance\_rules](#input\_balance\_rules) | An object that contains the listener, target group, and health check configuration.
It consist of maps of applications like follows:
balance\_rules = {
"application\_name" = {
protocol = "communication protocol, since this is a NLB module accepted values are TCP or TLS"
port = "communication port"
target\_type = "type of the target that will be attached to a target group, no defaults here, has to be provided explicitly (regardless the defaults terraform could accept)"
target\_port = "for target types supporting port values, the port number on which the target accepts communication, defaults to the communication port value"
targets = "a map of targets, where key is the target name (used to create a name for the target attachment), value is the target ID (IP, resource ID, etc - the actual value depends on the target type)"
target\_az = "This parameter is not supported if the target type of the target group is instance or alb. If the target type is ip and the IP address is outside the VPC, this parameter is required."
health\_check\_port = "port used by the target group healthcheck, if ommited, `traffic-port` will be used"
threshold = "number of consecutive health checks before considering target healthy or unhealthy, defaults to 3"
interval = "time between each health check, between 5 and 300 seconds, defaults to 30s"
preserve\_client\_ip = "whether client IP preservation is enabled, by default disabled for protocols TCP and TLS, enabled for others"

certificate\_arn = "(TLS ONLY) this is the arn of a certificate"
alpn\_policy = "(TLS ONLY) ALPN policy name, for possible values check (terraform documentation)[https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb\_listener#alpn\_policy], defaults to `None`"
}
}
The `application_name` key is valid only for letters, numbers and a dash (`-`) - that's an AWS limitation.



`protocol` and `port` are used for `listener`, `target group` and `target group attachment`. Partially also for health checks (see below).



All listeners are always of forward action.



If you add FWs as targets, make sure you use `target_type = "ip"` and you provide the correct FW IPs in `target` map. IPs should be from the subnet set that the Load Balancer was created in. An example on how to feed this variable with data:
fw\_instance\_ips = { for k, v in var.vmseries : k => module.vmseries[k].interfaces["untrust"].private\_ip }
For format of `var.vmseries` check the (`vmseries` module)[../vmseries/README.md]. 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:
{
vm01 = "1.1.1.1"
vm02 = "2.2.2.2"
...
}


Healthchecks are by default of type TCP. Reason for that is the fact, that HTTP requests might flow through the FW to the actual application. So instead of checking the status of the FW we might check the status of the application.

You have an option to specify a health check port. This way you can set up a Management Profile with an Administrative Management Service limited only to NLBs private IPs and use a port for that service as the health check port. This way you make sure you separate the actual health check from the application rule's port.



EXAMPLE
balance\_rules = {
"HTTPS-APP" = {
protocol = "TCP"
port = "443"
health\_check\_port = "80"
threshold = 2
interval = 10
target\_port = 8443
target\_type = "ip"
targets = { for k, v in var.vmseries : k => module.vmseries[k].interfaces["untrust"].private\_ip }
target\_az = "all"
stickiness = true
preserve\_client\_ip = true
}
}
| `any` | n/a | yes | +| [balance\_rules](#input\_balance\_rules) | An object that contains the listener, target group, and health check configuration.
It consist of maps of applications like follows:
balance\_rules = {
"application\_name" = {
protocol = "communication protocol, since this is a NLB module accepted values are TCP or TLS"
port = "communication port"
target\_type = "type of the target that will be attached to a target group, no defaults here, has to be provided explicitly (regardless the defaults terraform could accept)"
target\_port = "for target types supporting port values, the port number on which the target accepts communication, defaults to the communication port value"
targets = "a map of targets, where key is the target name (used to create a name for the target attachment), value is the target ID (IP, resource ID, etc - the actual value depends on the target type)"
target\_az = "This parameter is not supported if the target type of the target group is instance or alb. If the target type is ip and the IP address is outside the VPC, this parameter is required."
health\_check\_port = "port used by the target group healthcheck, if ommited, `traffic-port` will be used"
threshold = "number of consecutive health checks before considering target healthy or unhealthy, defaults to 3"
interval = "time between each health check, between 5 and 300 seconds, defaults to 30s"
preserve\_client\_ip = "whether client IP preservation is enabled, by default disabled for protocols TCP and TLS, enabled for others"

certificate\_arn = "(TLS ONLY) this is the arn of a certificate"
alpn\_policy = "(TLS ONLY) ALPN policy name, for possible values check (terraform documentation)[https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb\_listener#alpn\_policy], defaults to `None`"
}
}
The `application_name` key is valid only for letters, numbers and a dash (`-`) - that's an AWS limitation.



`protocol` and `port` are used for `listener`, `target group` and `target group attachment`. Partially also for health checks (see below).



All listeners are always of forward action.



If you add FWs as targets, make sure you use `target_type = "ip"` and you provide the correct FW IPs in `target` map. IPs should be from the subnet set that the Load Balancer was created in. An example on how to feed this variable with data:
fw\_instance\_ips = { for k, v in var.vmseries : k => module.vmseries[k].interfaces["untrust"].private\_ip }
For format of `var.vmseries` check the (`vmseries` module)[../vmseries/README.md]. 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:
{
vm01 = "1.1.1.1"
vm02 = "2.2.2.2"
...
}


Healthchecks are by default of type TCP. Reason for that is the fact, that HTTP requests might flow through the FW to the actual application. So instead of checking the status of the FW we might check the status of the application.

You have an option to specify a health check port. This way you can set up a Management Profile with an Administrative Management Service limited only to NLBs private IPs and use a port for that service as the health check port. This way you make sure you separate the actual health check from the application rule's port.



EXAMPLE
balance\_rules = {
"HTTPS-APP" = {
protocol = "TCP"
port = "443"
health\_check\_port = "80"
threshold = 2
interval = 10
target\_port = 8443
target\_type = "ip"
targets = { for k, v in var.vmseries : k => module.vmseries[k].interfaces["untrust"].private\_ip }
target\_az = "all"
stickiness = true
preserve\_client\_ip = true
}
}
|
map(object({
protocol = string
port = string
health\_check\_port = optional(string, "traffic-port")
threshold = optional(number)
interval = optional(number)
target\_port = optional(string)
target\_type = string
targets = map(string)
target\_az = optional(string)
preserve\_client\_ip = optional(bool)
stickiness = optional(bool)
certificate\_arn = optional(string)
alpn\_policy = optional(string)
}))
| n/a | yes | | [configure\_access\_logs](#input\_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 | | [create\_dedicated\_eips](#input\_create\_dedicated\_eips) | If set to `true`, a set of EIPs will be created for each zone/subnet. Otherwise AWS will handle IP management. | `bool` | `false` | no | | [enable\_cross\_zone\_load\_balancing](#input\_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 | diff --git a/products/terraform/docs/swfw/aws/vmseries/modules/panorama.md b/products/terraform/docs/swfw/aws/vmseries/modules/panorama.md index 88c593683..ddf696f1d 100644 --- a/products/terraform/docs/swfw/aws/vmseries/modules/panorama.md +++ b/products/terraform/docs/swfw/aws/vmseries/modules/panorama.md @@ -68,7 +68,7 @@ No modules. | [create\_public\_ip](#input\_create\_public\_ip) | If true, create an Elastic IP address for Panorama. | `bool` | `false` | no | | [ebs\_encrypted](#input\_ebs\_encrypted) | Whether to enable EBS encryption on root volume. | `bool` | `true` | no | | [ebs\_kms\_key\_alias](#input\_ebs\_kms\_key\_alias) | The alias for the customer managed KMS key to use for volume encryption.
If this is set to `null` the default master key that protects EBS volumes will be used | `string` | `"alias/aws/ebs"` | no | -| [ebs\_volumes](#input\_ebs\_volumes) | List of EBS volumes to create and attach to Panorama.
Available options:
- `name` (Optional) Name tag for the EBS volume. If not provided defaults to the value of `var.name`.
- `ebs_device_name` (Required) The EBS device name to expose to the instance (for example, /dev/sdh or xvdh).
See [Device Naming on Linux Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html#available-ec2-device-names) for more information.
- `ebs_size` (Optional) The size of the EBS volume in GiBs. Defaults to 2000 GiB.
- `force_detach` (Optional) Set to true if you want to force the volume to detach. Useful if previous attempts failed, but use this option only as a last resort, as this can result in data loss.
- `skip_destroy` (Optional) Set this to true if you do not wish to detach the volume from the instance to which it is attached at destroy time, and instead just remove the attachment from Terraform state.
This is useful when destroying an instance attached to third-party volumes.

Note: Terraform must be running with credentials which have the `GenerateDataKeyWithoutPlaintext` permission on the specified KMS key
as required by the [EBS KMS CMK volume provisioning process](https://docs.aws.amazon.com/kms/latest/developerguide/services-ebs.html#ebs-cmk) to prevent a volume from being created and almost immediately deleted.
If null, the default EBS encryption KMS key in the current region is used.

Example:
ebs\_volumes = [
{
name = "ebs-1"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
{
name = "ebs-2"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
{
name = "ebs-3"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
]
| `list(any)` | `[]` | no | +| [ebs\_volumes](#input\_ebs\_volumes) | List of EBS volumes to create and attach to Panorama.
Available options:
- `name` (Optional) Name tag for the EBS volume. If not provided defaults to the value of `var.name`.
- `ebs_device_name` (Required) The EBS device name to expose to the instance (for example, /dev/sdh or xvdh).
See [Device Naming on Linux Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html#available-ec2-device-names) for more information.
- `ebs_size` (Optional) The size of the EBS volume in GiBs. Defaults to 2000 GiB.
- `force_detach` (Optional) Set to true if you want to force the volume to detach. Useful if previous attempts failed, but use this option only as a last resort, as this can result in data loss.
- `skip_destroy` (Optional) Set this to true if you do not wish to detach the volume from the instance to which it is attached at destroy time, and instead just remove the attachment from Terraform state.
This is useful when destroying an instance attached to third-party volumes.

Note: Terraform must be running with credentials which have the `GenerateDataKeyWithoutPlaintext` permission on the specified KMS key
as required by the [EBS KMS CMK volume provisioning process](https://docs.aws.amazon.com/kms/latest/developerguide/services-ebs.html#ebs-cmk) to prevent a volume from being created and almost immediately deleted.
If null, the default EBS encryption KMS key in the current region is used.

Example:
ebs\_volumes = [
{
name = "ebs-1"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
{
name = "ebs-2"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
{
name = "ebs-3"
ebs\_device\_name = "/dev/sdb"
ebs\_size = "2000"
},
]
|
list(object({
name = optional(string)
ebs\_device\_name = string
ebs\_size = optional(string, "2000")
force\_detach = optional(bool, false)
skip\_destroy = optional(bool, false)
}))
| `[]` | no | | [eip\_domain](#input\_eip\_domain) | Indicates if this EIP is for use in VPC | `string` | `"vpc"` | no | | [enable\_imdsv2](#input\_enable\_imdsv2) | Whether to enable IMDSv2 on the EC2 instance.
Support for this feature has been added in VM-Series Plugin [3.0.0](https://docs.paloaltonetworks.com/plugins/vm-series-and-panorama-plugins-release-notes/vm-series-plugin/vm-series-plugin-30/vm-series-plugin-300#id126d0957-95d7-4b29-9147-fff20027986e), which in turn requires PAN-OS version 10.2.0 at minimum. | `string` | `false` | no | | [enable\_monitoring](#input\_enable\_monitoring) | (Optional) If true, the launched EC2 instance will have detailed monitoring enabled. | `bool` | `false` | no | diff --git a/products/terraform/docs/swfw/aws/vmseries/modules/subnet_set.md b/products/terraform/docs/swfw/aws/vmseries/modules/subnet_set.md index 54c945d4a..8689271ac 100644 --- a/products/terraform/docs/swfw/aws/vmseries/modules/subnet_set.md +++ b/products/terraform/docs/swfw/aws/vmseries/modules/subnet_set.md @@ -85,7 +85,7 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [cidrs](#input\_cidrs) | Map describing configuration of subnets and route tables to create and/or use in the set.
Keys are CIDR blocks, values can consist of following items:
- `create_subnet` - (Optional\|bool) When `true` (default), subnet is created, otherwise existing one is used.
- `create_route_table` - (Optional\|bool) When `true` a dedicated route table is created, unless existing subnet is used.
- `associate_route_table` - (Optional\|bool) Unless set to `false`, route table is associated with the subnet.
- `existing_route_table_id` - (Optional\|string) Id of an existing route table to associate with the subnet.
- `name` - (Optional\|string) Name (tag) of a subnet and, optionally a route table, to create or use. Defaults to set name appended with zone letter id.
- `route_table_name` - (Optional\|string) Name (tag) of a subnet and, optionally a route table, to create or use. Defaults to `name` value.
- `ipv6_cidr_block` - (Optional\|string) IPv6 CIDR block. The subnet size must use a /64 prefix length.
- `map_public_ip_on_launch` - (Optional\|bool) Specify true to indicate that instances launched into the subnet should be assigned a public IP address.
- `local_tags` - (Optional\|map) Map of tags to assign to created resources. | `map(any)` | n/a | yes | +| [cidrs](#input\_cidrs) | Map describing configuration of subnets and route tables to create and/or use in the set.
Keys are CIDR blocks, values can consist of following items:
- `create_subnet` - (Optional\|bool) When `true` (default), subnet is created, otherwise existing one is used.
- `create_route_table` - (Optional\|bool) When `true` a dedicated route table is created, unless existing subnet is used.
- `associate_route_table` - (Optional\|bool) Unless set to `false`, route table is associated with the subnet.
- `existing_route_table_id` - (Optional\|string) Id of an existing route table to associate with the subnet.
- `name` - (Optional\|string) Name (tag) of a subnet and, optionally a route table, to create or use. Defaults to set name appended with zone letter id.
- `route_table_name` - (Optional\|string) Name (tag) of a subnet and, optionally a route table, to create or use. Defaults to `name` value.
- `ipv6_cidr_block` - (Optional\|string) IPv6 CIDR block. The subnet size must use a /64 prefix length.
- `map_public_ip_on_launch` - (Optional\|bool) Specify true to indicate that instances launched into the subnet should be assigned a public IP address.
- `local_tags` - (Optional\|map) Map of tags to assign to created resources. |
map(object({
az = string
create\_subnet = optional(bool, true)
create\_route\_table = optional(bool, true)
associate\_route\_table = optional(bool, true)
existing\_route\_table\_id = optional(string)
name = optional(string)
route\_table\_name = optional(string)
ipv6\_cidr = optional(string)
map\_public\_ip\_on\_launch = optional(bool)
local\_tags = optional(map(string))
}))
| n/a | yes | | [create\_shared\_route\_table](#input\_create\_shared\_route\_table) | Boolean flag whether to create a shared route tables. | `bool` | `false` | no | | [global\_tags](#input\_global\_tags) | Optional map of arbitrary tags to apply to all the created resources. | `map(string)` | `{}` | no | | [has\_secondary\_cidrs](#input\_has\_secondary\_cidrs) | The input that depends on the secondary CIDR ranges of the VPC `vpc_id`. The actual value (true or false) is ignored, the input is used only to delay subnet creation until the secondary CIDR ranges are processed by Terraform. | `bool` | `true` | no | diff --git a/products/terraform/docs/swfw/aws/vmseries/modules/vmseries.md b/products/terraform/docs/swfw/aws/vmseries/modules/vmseries.md index 084deb5d1..d2144d279 100644 --- a/products/terraform/docs/swfw/aws/vmseries/modules/vmseries.md +++ b/products/terraform/docs/swfw/aws/vmseries/modules/vmseries.md @@ -70,7 +70,6 @@ No modules. | [airs\_deployment](#input\_airs\_deployment) | Deployment type VM-Series (False) or AI Runtime Security (True) | `bool` | `false` | no | | [airs\_instance\_type](#input\_airs\_instance\_type) | EC2 instance type. | `string` | `"c6in.xlarge"` | no | | [airs\_product\_code](#input\_airs\_product\_code) | Product code corresponding to a chosen AIRS license type model - by default - BYOL.
To check the available license type models and their codes, please refer to the | `string` | `"b261y39exndwe1ltro1tqpeog"` | no | -| [airs\_version](#input\_airs\_version) | AI Runtime Security version to deploy.
To list all available AIRS versions, run the command provided below.
Please have in mind that the `product-code` may need to be updated - check the `vmseries_product_code` variable for more information.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=b261y39exndwe1ltro1tqpeog" "Name=name,Values=PA-AI-Runtime-Security-AWS*" --output json --query "Images[].Description" \| grep -o 'PA-AI-Runtime-Security-AWS-.*' \| sort
| `string` | `"11.2.5-h1"` | no | | [bootstrap\_options](#input\_bootstrap\_options) | VM-Series bootstrap options to provide using instance user data. Contents determine type of bootstap method to use.
If empty (the default), bootstrap process is not triggered at all.
For more information on available methods, please refer to VM-Series documentation for specific version.
For 10.0 docs are available [here](https://docs.paloaltonetworks.com/vm-series/10-0/vm-series-deployment/bootstrap-the-vm-series-firewall.html). | `string` | `""` | no | | [ebs\_encrypted](#input\_ebs\_encrypted) | Whether to enable EBS encryption on volumes. | `bool` | `true` | no | | [ebs\_kms\_key\_alias](#input\_ebs\_kms\_key\_alias) | The alias for the customer managed KMS key to use for volume encryption. Should be prepended with the word "alias" followed by a forward slash (alias/example-key-alias).
If `null` (the default), the default master key that protects EBS volumes will be used. | `string` | `"alias/aws/ebs"` | no | @@ -81,13 +80,13 @@ No modules. | [iam\_instance\_profile](#input\_iam\_instance\_profile) | IAM instance profile. | `string` | `null` | no | | [include\_deprecated\_ami](#input\_include\_deprecated\_ami) | In certain scenarios, customers may deploy a VM-Series instance through the marketplace,
only to later discover that the ami has been deprecated, resulting in pipeline failures.
Setting the specified parameter to `true` will enable the continued use of deprecated AMIs,
mitigating this issue. | `bool` | `false` | no | | [instance\_type](#input\_instance\_type) | EC2 instance type. | `string` | `"m5.xlarge"` | no | -| [interfaces](#input\_interfaces) | Map of the network interface specifications.
If "mgmt-interface-swap" bootstrap option is enabled, ensure dataplane interface `device_index` is set to 0 and the firewall management interface `device_index` is set to 1.
Available options:
- `device_index` = (Required\|int) Determines order in which interfaces are attached to the instance. Interface with `0` is attached at boot time.
- `subnet_id` = (Required\|string) Subnet ID to create the ENI in.
- `name` = (Optional\|string) Name tag for the ENI. Defaults to instance name suffixed by map's key.
- `description` = (Optional\|string) A descriptive name for the ENI.
- `create_public_ip` = (Optional\|bool) Whether to create a public IP for the ENI. Defaults to false.
- `eip_allocation_id` = (Optional\|string) Associate an existing EIP to the ENI.
- `private_ips` = (Optional\|list) List of private IPs to assign to the ENI. If not set, dynamic allocation is used.
- `ipv6_address_count` = (Optional\|number) Number of IPv6 addresses that will be assigned to the interface (use only when IPv6 enabled in the subnet). Defaults to null.
- `public_ipv4_pool` = (Optional\|string) EC2 IPv4 address pool identifier.
- `source_dest_check` = (Optional\|bool) Whether to enable source destination checking for the ENI. Defaults to false.
- `security_group_ids` = (Optional\|list) A list of Security Group IDs to assign to this interface. Defaults to null.

Example:
interfaces = {
mgmt = {
device\_index = 0
subnet\_id = aws\_subnet.mgmt.id
name = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
security\_group\_ids = ["sg-123456"]
},
public = {
device\_index = 1
subnet\_id = aws\_subnet.public.id
name = "public"
create\_public\_ip = true
},
private = {
device\_index = 2
subnet\_id = aws\_subnet.private.id
name = "private"
},
]
| `map(any)` | n/a | yes | +| [interfaces](#input\_interfaces) | Map of the network interface specifications.
If "mgmt-interface-swap" bootstrap option is enabled, ensure dataplane interface `device_index` is set to 0 and the firewall management interface `device_index` is set to 1.
Available options:
- `device_index` = (Required\|int) Determines order in which interfaces are attached to the instance. Interface with `0` is attached at boot time.
- `subnet_id` = (Required\|string) Subnet ID to create the ENI in.
- `name` = (Optional\|string) Name tag for the ENI. Defaults to instance name suffixed by map's key.
- `description` = (Optional\|string) A descriptive name for the ENI.
- `create_public_ip` = (Optional\|bool) Whether to create a public IP for the ENI. Defaults to false.
- `eip_allocation_id` = (Optional\|string) Associate an existing EIP to the ENI.
- `private_ips` = (Optional\|list) List of private IPs to assign to the ENI. If not set, dynamic allocation is used.
- `ipv6_address_count` = (Optional\|number) Number of IPv6 addresses that will be assigned to the interface (use only when IPv6 enabled in the subnet). Defaults to null.
- `public_ipv4_pool` = (Optional\|string) EC2 IPv4 address pool identifier.
- `source_dest_check` = (Optional\|bool) Whether to enable source destination checking for the ENI. Defaults to false.
- `security_group_ids` = (Optional\|list) A list of Security Group IDs to assign to this interface. Defaults to null.

Example:
interfaces = {
mgmt = {
device\_index = 0
subnet\_id = aws\_subnet.mgmt.id
name = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
security\_group\_ids = ["sg-123456"]
},
public = {
device\_index = 1
subnet\_id = aws\_subnet.public.id
name = "public"
create\_public\_ip = true
},
private = {
device\_index = 2
subnet\_id = aws\_subnet.private.id
name = "private"
},
]
|
map(object({
device\_index = number
subnet\_id = string
name = optional(string)
description = optional(string)
create\_public\_ip = optional(bool, false)
eip\_allocation\_id = optional(string)
private\_ips = optional(list(string))
ipv6\_address\_count = optional(number, null)
public\_ipv4\_pool = optional(string)
source\_dest\_check = optional(bool, false)
security\_group\_ids = optional(list(string), null)
}))
| n/a | yes | | [name](#input\_name) | Name of the VM-Series instance. | `string` | `null` | no | | [ssh\_key\_name](#input\_ssh\_key\_name) | Name of AWS keypair to associate with instances. | `string` | n/a | yes | | [tags](#input\_tags) | Map of additional tags to apply to all resources. | `map(any)` | `{}` | no | | [vmseries\_ami\_id](#input\_vmseries\_ami\_id) | Specific AMI ID to use for VM-Series instance.
If `null` (the default), `vmseries_version` and `vmseries_product_code` vars are used to determine a public image to use. | `string` | `null` | no | | [vmseries\_product\_code](#input\_vmseries\_product\_code) | Product code corresponding to a chosen VM-Series license type model - by default - BYOL.
To check the available license type models and their codes, please refer to the
[VM-Series documentation](https://docs.paloaltonetworks.com/vm-series/10-0/vm-series-deployment/set-up-the-vm-series-firewall-on-aws/deploy-the-vm-series-firewall-on-aws/obtain-the-ami/get-amazon-machine-image-ids.html) | `string` | `"6njl1pau431dv1qxipg63mvah"` | no | -| [vmseries\_version](#input\_vmseries\_version) | VM-Series Firewall version to deploy.
To list all available VM-Series versions, run the command provided below.
Please have in mind that the `product-code` may need to be updated - check the `vmseries_product_code` variable for more information.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=6njl1pau431dv1qxipg63mvah" "Name=name,Values=PA-VM-AWS*" --output json --query "Images[].Description" \| grep -o 'PA-VM-AWS-.*' \| sort
| `string` | `"10.2.9-h1"` | no | +| [vmseries\_version](#input\_vmseries\_version) | VM-Series Firewall/AIRS version to deploy.
To list all available VM-Series versions, run the command provided below.
Please have in mind that the `product-code` may need to be updated - check the `vmseries_product_code` variable for more information.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=6njl1pau431dv1qxipg63mvah" "Name=name,Values=PA-VM-AWS*" --output json --query "Images[].Description" \| grep -o 'PA-VM-AWS-.\*' \| sort
To list all available AIRS versions, run the command provided below.
aws ec2 describe-images --region us-west-1 --filters "Name=product-code,Values=b261y39exndwe1ltro1tqpeog" "Name=name,Values=PA-AI-Runtime-Security-AWS-\*" --output json --query "Images[].Name" \| grep -o 'PA-AI-Runtime-Security-AWS-.*' \| sort
| `string` | `"11.1.4-h7"` | no | ### Outputs diff --git a/products/terraform/docs/swfw/aws/vmseries/modules/vpc.md b/products/terraform/docs/swfw/aws/vmseries/modules/vpc.md index 55f2ec2d7..49c07bf48 100644 --- a/products/terraform/docs/swfw/aws/vmseries/modules/vpc.md +++ b/products/terraform/docs/swfw/aws/vmseries/modules/vpc.md @@ -100,7 +100,7 @@ No modules. | [enable\_dns\_support](#input\_enable\_dns\_support) | A boolean flag to enable/disable DNS support in the VPC. [Defaults true](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#enable_dns_support). | `bool` | `null` | no | | [global\_tags](#input\_global\_tags) | Optional map of arbitrary tags to apply to all the created resources. | `map(string)` | `{}` | no | | [instance\_tenancy](#input\_instance\_tenancy) | VPC level [instance tenancy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#instance_tenancy). | `string` | `null` | no | -| [nacls](#input\_nacls) | The `nacls` variable is a map of maps, where each map represents an AWS NACL.

Example:
nacls = {
trusted\_path\_monitoring = {
name = "trusted-path-monitoring"
rules = {
block\_outbound\_icmp = {
rule\_number = 110
egress = true
protocol = "icmp"
rule\_action = "deny"
cidr\_block = "10.100.1.0/24"
from\_port = null
to\_port = null
}
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
}
}
}
}
| `any` | `{}` | no | +| [nacls](#input\_nacls) | The `nacls` variable is a map of maps, where each map represents an AWS NACL.

Example:
nacls = {
trusted\_path\_monitoring = {
name = "trusted-path-monitoring"
rules = {
block\_outbound\_icmp = {
rule\_number = 110
egress = true
protocol = "icmp"
rule\_action = "deny"
cidr\_block = "10.100.1.0/24"
from\_port = null
to\_port = null
}
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
}
}
}
}
|
map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
}))
| `{}` | no | | [name](#input\_name) | Name of the VPC to create or use. | `string` | n/a | yes | | [name\_internet\_gateway](#input\_name\_internet\_gateway) | Name of the IGW to create or use. | `string` | `null` | no | | [name\_vpn\_gateway](#input\_name\_vpn\_gateway) | Name of the VPN gateway to create. | `string` | `null` | no | @@ -108,7 +108,7 @@ No modules. | [route\_table\_internet\_gateway](#input\_route\_table\_internet\_gateway) | Name of route table for the IGW. | `string` | `null` | no | | [route\_table\_vpn\_gateway](#input\_route\_table\_vpn\_gateway) | Name of the route table for VPN gateway. | `string` | `null` | no | | [secondary\_cidr\_blocks](#input\_secondary\_cidr\_blocks) | Secondary CIDR block to assign to a new VPC. | `list(string)` | `[]` | no | -| [security\_groups](#input\_security\_groups) | The `security_groups` variable is a map of maps, where each map represents an AWS Security Group.
The key of each entry acts as the Security Group name.
List of available attributes of each Security Group entry:
- `rules`: A list of objects representing a Security Group rule. The key of each entry acts as the name of the rule and
needs to be unique across all rules in the Security Group.
List of attributes available to define a Security Group rule:
- `description`: Security Group description.
- `type`: Specifies if rule will be evaluated on ingress (inbound) or egress (outbound) traffic.
- `cidr_blocks`: List of CIDR blocks - for ingress, determines the traffic that can reach your instance. For egress
Determines the traffic that can leave your instance, and where it can go.
- `ipv6_cidr_blocks`: List of IPv6 CIDR blocks - for ingress, determines the traffic that can reach your instance. For egress
Determines the traffic that can leave your instance, and where it can go. Defaults to null.
- `prefix_list_ids`: List of Prefix List IDs
- `self`: security group itself will be added as a source to the rule. Cannot be specified with cidr\_blocks, or security\_groups.
- `source_security_groups`: list of security group IDs to be used as a source to the rule. Cannot be specified with cidr\_blocks, or self.


Example:
security\_groups = {
vmseries-mgmt = {
name = "vmseries-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"]
}
all-outbound-ipv6 = {
description = "Permit All traffic outbound"
type = "egress", from\_port = "0", to\_port = "0", protocol = "-1"
cidr\_blocks = ["::/0"]
}
https-inbound-private = {
description = "Permit HTTPS for VM-Series Management"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
cidr\_blocks = ["10.0.0.0/8"]
}
https-inbound-eip = {
description = "Permit HTTPS for VM-Series Management from known public IPs"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
cidr\_blocks = ["100.100.100.100/32"]
}
ssh-inbound-eip = {
description = "Permit SSH for VM-Series Management from known public IPs"
type = "ingress", from\_port = "22", to\_port = "22", protocol = "tcp"
cidr\_blocks = ["100.100.100.100/32"]
}
https-inbound-self = {
description = "Permit HTTPS from instances with the same security group"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
self = true
}
https-inbound-security-groups = {
description = "Permit HTTPS traffic for the resources associated with the specified security group"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
source\_security\_groups = ["sg-1a2b3c4d5e6f7g8h9i"]
}
https-inbound-prefix-list = {
description = "Permit HTTPS for VM-Series Management for IPs in managed prefix list"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
prefix\_list\_ids = ["pl-1a2b3c4d5e6f7g8h9i"]
}
}
}
}
| `any` | `{}` | no | +| [security\_groups](#input\_security\_groups) | The `security_groups` variable is a map of maps, where each map represents an AWS Security Group.
The key of each entry acts as the Security Group name.
List of available attributes of each Security Group entry:
- `rules`: A map of objects representing a Security Group rule. The key of each entry
needs to be unique across all rules in the Security Group.
List of attributes available to define a Security Group rule:
- `description`: Security Group description.
- `type`: Specifies if rule will be evaluated on ingress (inbound) or egress (outbound) traffic.
- `cidr_blocks`: List of CIDR blocks - for ingress, determines the traffic that can reach your instance. For egress
Determines the traffic that can leave your instance, and where it can go.
- `ipv6_cidr_blocks`: List of IPv6 CIDR blocks - for ingress, determines the traffic that can reach your instance. For egress
Determines the traffic that can leave your instance, and where it can go. Defaults to null.
- `prefix_list_ids`: List of Prefix List IDs
- `self`: security group itself will be added as a source to the rule. Cannot be specified with cidr\_blocks, or security\_groups.
- `source_security_groups`: list of security group IDs to be used as a source to the rule. Cannot be specified with cidr\_blocks, or self.


Example:
security\_groups = {
vmseries-mgmt = {
name = "vmseries-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"]
}
all-outbound-ipv6 = {
description = "Permit All traffic outbound"
type = "egress", from\_port = "0", to\_port = "0", protocol = "-1"
cidr\_blocks = ["::/0"]
}
https-inbound-private = {
description = "Permit HTTPS for VM-Series Management"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
cidr\_blocks = ["10.0.0.0/8"]
}
https-inbound-eip = {
description = "Permit HTTPS for VM-Series Management from known public IPs"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
cidr\_blocks = ["100.100.100.100/32"]
}
ssh-inbound-eip = {
description = "Permit SSH for VM-Series Management from known public IPs"
type = "ingress", from\_port = "22", to\_port = "22", protocol = "tcp"
cidr\_blocks = ["100.100.100.100/32"]
}
https-inbound-self = {
description = "Permit HTTPS from instances with the same security group"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
self = true
}
https-inbound-security-groups = {
description = "Permit HTTPS traffic for the resources associated with the specified security group"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
source\_security\_groups = ["sg-1a2b3c4d5e6f7g8h9i"]
}
https-inbound-prefix-list = {
description = "Permit HTTPS for VM-Series Management for IPs in managed prefix list"
type = "ingress", from\_port = "443", to\_port = "443", protocol = "tcp"
prefix\_list\_ids = ["pl-1a2b3c4d5e6f7g8h9i"]
}
}
}
}
|
map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
}))
| `{}` | no | | [use\_internet\_gateway](#input\_use\_internet\_gateway) | If an existing VPC is provided and has IG attached, set to `true` to reuse it. | `bool` | `false` | no | | [vpc\_tags](#input\_vpc\_tags) | Optional map of arbitrary tags to apply to VPC resource. | `map` | `{}` | no | | [vpn\_gateway\_amazon\_side\_asn](#input\_vpn\_gateway\_amazon\_side\_asn) | ASN for the Amazon side of the gateway. | `string` | `null` | no | diff --git a/products/terraform/docs/swfw/aws/vmseries/modules/vpn.md b/products/terraform/docs/swfw/aws/vmseries/modules/vpn.md index efe8d5920..5ceee6240 100644 --- a/products/terraform/docs/swfw/aws/vmseries/modules/vpn.md +++ b/products/terraform/docs/swfw/aws/vmseries/modules/vpn.md @@ -73,7 +73,7 @@ No modules. | [transit\_gateway\_associate\_route\_table\_id](#input\_transit\_gateway\_associate\_route\_table\_id) | TGW route table ID used to associate VPN attachments created by VPN connections | `string` | n/a | yes | | [transit\_gateway\_id](#input\_transit\_gateway\_id) | TGW's ID used by VPN connection | `string` | n/a | yes | | [transit\_gateway\_propagate\_route\_table\_id](#input\_transit\_gateway\_propagate\_route\_table\_id) | TGW route table ID into which VPN attachment will propagate routes received by BGP | `string` | n/a | yes | -| [vpn\_connection](#input\_vpn\_connection) | VPN connection defined by attributes:
- customer\_gateway\_id - (Required) The ID of the customer gateway.
- type - (Required) The type of VPN connection. The only type AWS supports at this time is "ipsec.1".
- transit\_gateway\_id - (Optional) The ID of the EC2 Transit Gateway.
- static\_routes\_only - (Optional, Default false) Whether the VPN connection uses static routes exclusively. Static routes must be used for devices that don't support BGP.
- enable\_acceleration - (Optional, Default false) Indicate whether to enable acceleration for the VPN connection. Supports only EC2 Transit Gateway.
- tags - (Optional) Tags to apply to the connection. If configured with a provider default\_tags configuration block present, tags with matching keys will overwrite those defined at the provider-level.
- local\_ipv4\_network\_cidr - (Optional, Default 0.0.0.0/0) The IPv4 CIDR on the customer gateway (on-premises) side of the VPN connection.
- local\_ipv6\_network\_cidr - (Optional, Default ::/0) The IPv6 CIDR on the customer gateway (on-premises) side of the VPN connection.
- outside\_ip\_address\_type - (Optional, Default PublicIpv4) Indicates if a Public S2S VPN or Private S2S VPN over AWS Direct Connect. Valid values are PublicIpv4 \| PrivateIpv4
- remote\_ipv4\_network\_cidr - (Optional, Default 0.0.0.0/0) The IPv4 CIDR on the AWS side of the VPN connection.
- remote\_ipv6\_network\_cidr - (Optional, Default ::/0) The IPv6 CIDR on the customer gateway (on-premises) side of the VPN connection.
- transport\_transit\_gateway\_attachment\_id - (Required when outside\_ip\_address\_type is set to PrivateIpv4). The attachment ID of the Transit Gateway attachment to Direct Connect Gateway. The ID is obtained through a data source only.
- tunnel\_inside\_ip\_version - (Optional, Default ipv4) Indicate whether the VPN tunnels process IPv4 or IPv6 traffic. Valid values are ipv4 \| ipv6. ipv6 Supports only EC2 Transit Gateway.
- tunnel1\_inside\_cidr - (Optional) The CIDR block of the inside IP addresses for the first VPN tunnel. Valid value is a size /30 CIDR block from the 169.254.0.0/16 range.
- tunnel2\_inside\_cidr - (Optional) The CIDR block of the inside IP addresses for the second VPN tunnel. Valid value is a size /30 CIDR block from the 169.254.0.0/16 range.
- tunnel1\_inside\_ipv6\_cidr - (Optional) The range of inside IPv6 addresses for the first VPN tunnel. Supports only EC2 Transit Gateway. Valid value is a size /126 CIDR block from the local fd00::/8 range.
- tunnel2\_inside\_ipv6\_cidr - (Optional) The range of inside IPv6 addresses for the second VPN tunnel. Supports only EC2 Transit Gateway. Valid value is a size /126 CIDR block from the local fd00::/8 range.
- tunnel1\_preshared\_key - (Optional) The preshared key of the first VPN tunnel. The preshared key must be between 8 and 64 characters in length and cannot start with zero(0). Allowed characters are alphanumeric characters, periods(.) and underscores(\_).
- tunnel2\_preshared\_key - (Optional) The preshared key of the second VPN tunnel. The preshared key must be between 8 and 64 characters in length and cannot start with zero(0). Allowed characters are alphanumeric characters, periods(.) and underscores(\_).
- tunnel1\_dpd\_timeout\_action - (Optional, Default clear) The action to take after DPD timeout occurs for the first VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart.
- tunnel2\_dpd\_timeout\_action - (Optional, Default clear) The action to take after DPD timeout occurs for the second VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart.
- tunnel1\_dpd\_timeout\_seconds - (Optional, Default 30) The number of seconds after which a DPD timeout occurs for the first VPN tunnel. Valid value is equal or higher than 30.
- tunnel2\_dpd\_timeout\_seconds - (Optional, Default 30) The number of seconds after which a DPD timeout occurs for the second VPN tunnel. Valid value is equal or higher than 30.
- tunnel1\_enable\_tunnel\_lifecycle\_control - (Optional, Default false) Turn on or off tunnel endpoint lifecycle control feature for the first VPN tunnel. Valid values are true \| false.
- tunnel2\_enable\_tunnel\_lifecycle\_control - (Optional, Default false) Turn on or off tunnel endpoint lifecycle control feature for the second VPN tunnel. Valid values are true \| false.
- tunnel1\_ike\_versions - (Optional) The IKE versions that are permitted for the first VPN tunnel. Valid values are ikev1 \| ikev2.
- tunnel2\_ike\_versions - (Optional) The IKE versions that are permitted for the second VPN tunnel. Valid values are ikev1 \| ikev2.
- tunnel1\_log\_options - (Required) Options for logging VPN tunnel activity:
- enabled - (Required) true if logs need to stored in CloudWatch logs
- log\_group - (Required) The name of the log group.
- retention\_in\_days - (Required) Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
- encrypted - (Required) true if logs need to be encrypted
- tunnel2\_log\_options - (Required) Options for logging VPN tunnel activity:
- enabled - (Required) Required if logs need to stored in CloudWatch logs
- log\_group - (Required) The name of the log group.
- retention\_in\_days - (Required) Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
- encrypted - (Required) true if logs need to be encrypted
- tunnel1\_phase1\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are 2 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel2\_phase1\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are 2 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel1\_phase1\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel2\_phase1\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel1\_phase1\_integrity\_algorithms - (Optional) One or more integrity algorithms that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel2\_phase1\_integrity\_algorithms - (Optional) One or more integrity algorithms that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel1\_phase1\_lifetime\_seconds - (Optional, Default 28800) The lifetime for phase 1 of the IKE negotiation for the first VPN tunnel, in seconds. Valid value is between 900 and 28800.
- tunnel2\_phase1\_lifetime\_seconds - (Optional, Default 28800) The lifetime for phase 1 of the IKE negotiation for the second VPN tunnel, in seconds. Valid value is between 900 and 28800.
- tunnel1\_phase2\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are 2 \| 5 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel2\_phase2\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are 2 \| 5 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel1\_phase2\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel2\_phase2\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel1\_phase2\_integrity\_algorithms - (Optional) List of one or more integrity algorithms that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel2\_phase2\_integrity\_algorithms - (Optional) List of one or more integrity algorithms that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel1\_phase2\_lifetime\_seconds - (Optional, Default 3600) The lifetime for phase 2 of the IKE negotiation for the first VPN tunnel, in seconds. Valid value is between 900 and 3600.
- tunnel2\_phase2\_lifetime\_seconds - (Optional, Default 3600) The lifetime for phase 2 of the IKE negotiation for the second VPN tunnel, in seconds. Valid value is between 900 and 3600.
- tunnel1\_rekey\_fuzz\_percentage - (Optional, Default 100) The percentage of the rekey window for the first VPN tunnel (determined by tunnel1\_rekey\_margin\_time\_seconds) during which the rekey time is randomly selected. Valid value is between 0 and 100.
- tunnel2\_rekey\_fuzz\_percentage - (Optional, Default 100) The percentage of the rekey window for the second VPN tunnel (determined by tunnel2\_rekey\_margin\_time\_seconds) during which the rekey time is randomly selected. Valid value is between 0 and 100.
- tunnel1\_rekey\_margin\_time\_seconds - (Optional, Default 540) The margin time, in seconds, before the phase 2 lifetime expires, during which the AWS side of the first VPN connection performs an IKE rekey. The exact time of the rekey is randomly selected based on the value for tunnel1\_rekey\_fuzz\_percentage. Valid value is between 60 and half of tunnel1\_phase2\_lifetime\_seconds.
- tunnel2\_rekey\_margin\_time\_seconds - (Optional, Default 540) The margin time, in seconds, before the phase 2 lifetime expires, during which the AWS side of the second VPN connection performs an IKE rekey. The exact time of the rekey is randomly selected based on the value for tunnel2\_rekey\_fuzz\_percentage. Valid value is between 60 and half of tunnel2\_phase2\_lifetime\_seconds.
- tunnel1\_replay\_window\_size - (Optional, Default 1024) The number of packets in an IKE replay window for the first VPN tunnel. Valid value is between 64 and 2048.
- tunnel2\_replay\_window\_size - (Optional, Default 1024) The number of packets in an IKE replay window for the second VPN tunnel. Valid value is between 64 and 2048.
- tunnel1\_startup\_action - (Optional, Default add) The action to take when the establishing the tunnel for the first VPN connection. By default, your customer gateway device must initiate the IKE negotiation and bring up the tunnel. Specify start for AWS to initiate the IKE negotiation. Valid values are add \| start.
- tunnel2\_startup\_action - (Optional, Default add) The action to take when the establishing the tunnel for the second VPN connection. By default, your customer gateway device must initiate the IKE negotiation and bring up the tunnel. Specify start for AWS to initiate the IKE negotiation. Valid values are add \| start. | `any` | n/a | yes | +| [vpn\_connection](#input\_vpn\_connection) | VPN connection defined by attributes:
- customer\_gateway\_id - (Required) The ID of the customer gateway.
- type - (Required) The type of VPN connection. The only type AWS supports at this time is "ipsec.1".
- transit\_gateway\_id - (Optional) The ID of the EC2 Transit Gateway.
- static\_routes\_only - (Optional, Default false) Whether the VPN connection uses static routes exclusively. Static routes must be used for devices that don't support BGP.
- enable\_acceleration - (Optional, Default false) Indicate whether to enable acceleration for the VPN connection. Supports only EC2 Transit Gateway.
- tags - (Optional) Tags to apply to the connection. If configured with a provider default\_tags configuration block present, tags with matching keys will overwrite those defined at the provider-level.
- local\_ipv4\_network\_cidr - (Optional, Default 0.0.0.0/0) The IPv4 CIDR on the customer gateway (on-premises) side of the VPN connection.
- local\_ipv6\_network\_cidr - (Optional, Default ::/0) The IPv6 CIDR on the customer gateway (on-premises) side of the VPN connection.
- outside\_ip\_address\_type - (Optional, Default PublicIpv4) Indicates if a Public S2S VPN or Private S2S VPN over AWS Direct Connect. Valid values are PublicIpv4 \| PrivateIpv4
- remote\_ipv4\_network\_cidr - (Optional, Default 0.0.0.0/0) The IPv4 CIDR on the AWS side of the VPN connection.
- remote\_ipv6\_network\_cidr - (Optional, Default ::/0) The IPv6 CIDR on the customer gateway (on-premises) side of the VPN connection.
- transport\_transit\_gateway\_attachment\_id - (Required when outside\_ip\_address\_type is set to PrivateIpv4). The attachment ID of the Transit Gateway attachment to Direct Connect Gateway. The ID is obtained through a data source only.
- tunnel\_inside\_ip\_version - (Optional, Default ipv4) Indicate whether the VPN tunnels process IPv4 or IPv6 traffic. Valid values are ipv4 \| ipv6. ipv6 Supports only EC2 Transit Gateway.
- tunnel1\_inside\_cidr - (Optional) The CIDR block of the inside IP addresses for the first VPN tunnel. Valid value is a size /30 CIDR block from the 169.254.0.0/16 range.
- tunnel2\_inside\_cidr - (Optional) The CIDR block of the inside IP addresses for the second VPN tunnel. Valid value is a size /30 CIDR block from the 169.254.0.0/16 range.
- tunnel1\_inside\_ipv6\_cidr - (Optional) The range of inside IPv6 addresses for the first VPN tunnel. Supports only EC2 Transit Gateway. Valid value is a size /126 CIDR block from the local fd00::/8 range.
- tunnel2\_inside\_ipv6\_cidr - (Optional) The range of inside IPv6 addresses for the second VPN tunnel. Supports only EC2 Transit Gateway. Valid value is a size /126 CIDR block from the local fd00::/8 range.
- tunnel1\_preshared\_key - (Optional) The preshared key of the first VPN tunnel. The preshared key must be between 8 and 64 characters in length and cannot start with zero(0). Allowed characters are alphanumeric characters, periods(.) and underscores(\_).
- tunnel2\_preshared\_key - (Optional) The preshared key of the second VPN tunnel. The preshared key must be between 8 and 64 characters in length and cannot start with zero(0). Allowed characters are alphanumeric characters, periods(.) and underscores(\_).
- tunnel1\_dpd\_timeout\_action - (Optional, Default clear) The action to take after DPD timeout occurs for the first VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart.
- tunnel2\_dpd\_timeout\_action - (Optional, Default clear) The action to take after DPD timeout occurs for the second VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart.
- tunnel1\_dpd\_timeout\_seconds - (Optional, Default 30) The number of seconds after which a DPD timeout occurs for the first VPN tunnel. Valid value is equal or higher than 30.
- tunnel2\_dpd\_timeout\_seconds - (Optional, Default 30) The number of seconds after which a DPD timeout occurs for the second VPN tunnel. Valid value is equal or higher than 30.
- tunnel1\_enable\_tunnel\_lifecycle\_control - (Optional, Default false) Turn on or off tunnel endpoint lifecycle control feature for the first VPN tunnel. Valid values are true \| false.
- tunnel2\_enable\_tunnel\_lifecycle\_control - (Optional, Default false) Turn on or off tunnel endpoint lifecycle control feature for the second VPN tunnel. Valid values are true \| false.
- tunnel1\_ike\_versions - (Optional) The IKE versions that are permitted for the first VPN tunnel. Valid values are ikev1 \| ikev2.
- tunnel2\_ike\_versions - (Optional) The IKE versions that are permitted for the second VPN tunnel. Valid values are ikev1 \| ikev2.
- tunnel1\_log\_options - (Required) Options for logging VPN tunnel activity:
- enabled - (Required) true if logs need to stored in CloudWatch logs
- log\_group - (Required) The name of the log group.
- retention\_in\_days - (Required) Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
- encrypted - (Required) true if logs need to be encrypted
- tunnel2\_log\_options - (Required) Options for logging VPN tunnel activity:
- enabled - (Required) Required if logs need to stored in CloudWatch logs
- log\_group - (Required) The name of the log group.
- retention\_in\_days - (Required) Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
- encrypted - (Required) true if logs need to be encrypted
- tunnel1\_phase1\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are 2 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel2\_phase1\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are 2 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel1\_phase1\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel2\_phase1\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel1\_phase1\_integrity\_algorithms - (Optional) One or more integrity algorithms that are permitted for the first VPN tunnel for phase 1 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel2\_phase1\_integrity\_algorithms - (Optional) One or more integrity algorithms that are permitted for the second VPN tunnel for phase 1 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel1\_phase1\_lifetime\_seconds - (Optional, Default 28800) The lifetime for phase 1 of the IKE negotiation for the first VPN tunnel, in seconds. Valid value is between 900 and 28800.
- tunnel2\_phase1\_lifetime\_seconds - (Optional, Default 28800) The lifetime for phase 1 of the IKE negotiation for the second VPN tunnel, in seconds. Valid value is between 900 and 28800.
- tunnel1\_phase2\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are 2 \| 5 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel2\_phase2\_dh\_group\_numbers - (Optional) List of one or more Diffie-Hellman group numbers that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are 2 \| 5 \| 14 \| 15 \| 16 \| 17 \| 18 \| 19 \| 20 \| 21 \| 22 \| 23 \| 24.
- tunnel1\_phase2\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel2\_phase2\_encryption\_algorithms - (Optional) List of one or more encryption algorithms that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are AES128 \| AES256 \| AES128-GCM-16 \| AES256-GCM-16.
- tunnel1\_phase2\_integrity\_algorithms - (Optional) List of one or more integrity algorithms that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel2\_phase2\_integrity\_algorithms - (Optional) List of one or more integrity algorithms that are permitted for the second VPN tunnel for phase 2 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512.
- tunnel1\_phase2\_lifetime\_seconds - (Optional, Default 3600) The lifetime for phase 2 of the IKE negotiation for the first VPN tunnel, in seconds. Valid value is between 900 and 3600.
- tunnel2\_phase2\_lifetime\_seconds - (Optional, Default 3600) The lifetime for phase 2 of the IKE negotiation for the second VPN tunnel, in seconds. Valid value is between 900 and 3600.
- tunnel1\_rekey\_fuzz\_percentage - (Optional, Default 100) The percentage of the rekey window for the first VPN tunnel (determined by tunnel1\_rekey\_margin\_time\_seconds) during which the rekey time is randomly selected. Valid value is between 0 and 100.
- tunnel2\_rekey\_fuzz\_percentage - (Optional, Default 100) The percentage of the rekey window for the second VPN tunnel (determined by tunnel2\_rekey\_margin\_time\_seconds) during which the rekey time is randomly selected. Valid value is between 0 and 100.
- tunnel1\_rekey\_margin\_time\_seconds - (Optional, Default 540) The margin time, in seconds, before the phase 2 lifetime expires, during which the AWS side of the first VPN connection performs an IKE rekey. The exact time of the rekey is randomly selected based on the value for tunnel1\_rekey\_fuzz\_percentage. Valid value is between 60 and half of tunnel1\_phase2\_lifetime\_seconds.
- tunnel2\_rekey\_margin\_time\_seconds - (Optional, Default 540) The margin time, in seconds, before the phase 2 lifetime expires, during which the AWS side of the second VPN connection performs an IKE rekey. The exact time of the rekey is randomly selected based on the value for tunnel2\_rekey\_fuzz\_percentage. Valid value is between 60 and half of tunnel2\_phase2\_lifetime\_seconds.
- tunnel1\_replay\_window\_size - (Optional, Default 1024) The number of packets in an IKE replay window for the first VPN tunnel. Valid value is between 64 and 2048.
- tunnel2\_replay\_window\_size - (Optional, Default 1024) The number of packets in an IKE replay window for the second VPN tunnel. Valid value is between 64 and 2048.
- tunnel1\_startup\_action - (Optional, Default add) The action to take when the establishing the tunnel for the first VPN connection. By default, your customer gateway device must initiate the IKE negotiation and bring up the tunnel. Specify start for AWS to initiate the IKE negotiation. Valid values are add \| start.
- tunnel2\_startup\_action - (Optional, Default add) The action to take when the establishing the tunnel for the second VPN connection. By default, your customer gateway device must initiate the IKE negotiation and bring up the tunnel. Specify start for AWS to initiate the IKE negotiation. Valid values are add \| start. |
object({
name = optional(string, "")
customer\_gateway\_id = string
type = optional(string, "ipsec.1")
transit\_gateway\_id = optional(string)
static\_routes\_only = optional(bool, false)
enable\_acceleration = optional(bool, false)
tags = optional(map(string))
local\_ipv4\_network\_cidr = optional(string, "0.0.0.0/0")
local\_ipv6\_network\_cidr = optional(string, "::/0")
outside\_ip\_address\_type = optional(string, "PublicIpv4")
remote\_ipv4\_network\_cidr = optional(string, "0.0.0.0/0")
remote\_ipv6\_network\_cidr = optional(string, "::/0")
tunnel\_inside\_ip\_version = optional(string, "ipv4")
tunnel1\_inside\_cidr = optional(string)
tunnel2\_inside\_cidr = optional(string)
tunnel1\_inside\_ipv6\_cidr = optional(string)
tunnel2\_inside\_ipv6\_cidr = optional(string)
tunnel1\_preshared\_key = optional(string)
tunnel2\_preshared\_key = optional(string)
tunnel1\_dpd\_timeout\_action = optional(string)
tunnel2\_dpd\_timeout\_action = optional(string)
tunnel1\_dpd\_timeout\_seconds = optional(number, 30)
tunnel2\_dpd\_timeout\_seconds = optional(number, 30)
tunnel1\_enable\_tunnel\_lifecycle\_control = optional(bool)
tunnel2\_enable\_tunnel\_lifecycle\_control = optional(bool)
tunnel1\_ike\_versions = optional(string)
tunnel2\_ike\_versions = optional(string)
tunnel1\_log\_options = object({
enabled = bool
log\_group = string
retention\_in\_days = number
encrypted = bool
})
tunnel2\_log\_options = object({
enabled = bool
log\_group = string
retention\_in\_days = number
encrypted = bool
})
tunnel1\_phase1\_dh\_group\_numbers = optional(list(string))
tunnel2\_phase1\_dh\_group\_numbers = optional(list(string))
tunnel1\_phase1\_encryption\_algorithms = optional(list(string))
tunnel2\_phase1\_encryption\_algorithms = optional(list(string))
tunnel1\_phase1\_integrity\_algorithms = optional(list(string))
tunnel2\_phase1\_integrity\_algorithms = optional(list(string))
tunnel1\_phase1\_lifetime\_seconds = optional(number, 28800)
tunnel2\_phase1\_lifetime\_seconds = optional(number, 28800)
tunnel1\_phase2\_dh\_group\_numbers = optional(list(string))
tunnel2\_phase2\_dh\_group\_numbers = optional(list(string))
tunnel1\_phase2\_encryption\_algorithms = optional(list(string))
tunnel2\_phase2\_encryption\_algorithms = optional(list(string))
tunnel1\_phase2\_integrity\_algorithms = optional(list(string))
tunnel2\_phase2\_integrity\_algorithms = optional(list(string))
tunnel1\_phase2\_lifetime\_seconds = optional(number, 3600)
tunnel2\_phase2\_lifetime\_seconds = optional(number, 3600)
tunnel1\_rekey\_fuzz\_percentage = optional(number, 100)
tunnel2\_rekey\_fuzz\_percentage = optional(number, 100)
tunnel1\_rekey\_margin\_time\_seconds = optional(number, 540)
tunnel2\_rekey\_margin\_time\_seconds = optional(number, 540)
tunnel1\_replay\_window\_size = optional(number, 1024)
tunnel2\_replay\_window\_size = optional(number, 1024)
tunnel1\_startup\_action = optional(string, "add")
tunnel2\_startup\_action = optional(string, "add")
})
| n/a | yes | | [vpn\_gateway\_id](#input\_vpn\_gateway\_id) | Virtual Private Gateway's ID used by VPN connection | `string` | n/a | yes | ### Outputs diff --git a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/centralized_design.md b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/centralized_design.md index b6645011d..38e7323a7 100644 --- a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/centralized_design.md +++ b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/centralized_design.md @@ -90,7 +90,8 @@ To enable access from the session manager, the Internet connection for a public | Name | Source | Version | |------|--------|---------| -| [app\_lb](#module\_app\_lb) | ../../modules/nlb | n/a | +| [app\_alb](#module\_app\_alb) | ../../modules/alb | n/a | +| [app\_nlb](#module\_app\_nlb) | ../../modules/nlb | n/a | | [gwlb](#module\_gwlb) | ../../modules/gwlb | n/a | | [gwlbe\_endpoint](#module\_gwlbe\_endpoint) | ../../modules/gwlb_endpoint_set | n/a | | [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | @@ -128,24 +129,27 @@ To enable access from the session manager, the Internet connection for a public | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `any` | n/a | yes | -| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `gwlb`: key of GWLB
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
gwlb = string
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
}))
| `{}` | no | -| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
}))
| `{}` | no | +| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `custom_names`: Optional map of names of the VPC Endpoints, used to override the default naming generated from the input `name`.
Each key is the Availability Zone identifier, for example `us-east-1b`.
- `gwlb`: key of GWLB. Required when GWLB Endpoint must connect to GWLB's service name
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint
- `cloudngfw_key`(optional): Key of the Cloud NGFW. Required when GWLB Endpoint must connect to Cloud NGFW's service name

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
custom\_names = optional(map(string), {})
gwlb = optional(string)
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
delay = optional(number, 0)
tags = optional(map(string))
cloudngfw\_key = optional(string)
}))
| `{}` | no | +| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
tg\_name = optional(string)
target\_instances = optional(map(object({
id = string
})), {})
acceptance\_required = optional(bool, false)
allowed\_principals = optional(list(string), [])
deregistration\_delay = optional(number)
health\_check\_enabled = optional(bool)
health\_check\_interval = optional(number, 5)
health\_check\_matcher = optional(string)
health\_check\_path = optional(string)
health\_check\_port = optional(number, 80)
health\_check\_protocol = optional(string)
health\_check\_timeout = optional(number)
healthy\_threshold = optional(number, 3)
unhealthy\_threshold = optional(number, 3)
stickiness\_type = optional(string)
rebalance\_flows = optional(string, "no\_rebalance")
lb\_tags = optional(map(string), {})
lb\_target\_group\_tags = optional(map(string), {})
endpoint\_service\_tags = optional(map(string), {})
enable\_lb\_deletion\_protection = optional(bool)
}))
| `{}` | no | | [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | n/a | yes | -| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `name`: name of NAT Gateway
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
natgws = {
security\_nat\_gw = {
name = "natgw"
vpc = "security\_vpc"
subnet\_group = "natgw"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
}))
| `{}` | no | -| [panorama\_attachment](#input\_panorama\_attachment) | A object defining TGW attachment and CIDR for Panorama.

Following properties are available:
- `transit_gateway_attachment_id`: ID of attachment for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
transit\_gateway\_attachment\_id = "tgw-attach-123456789"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
transit\_gateway\_attachment\_id = string
vpc\_cidr = string
})
| `null` | no | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | +| [panorama\_attachment](#input\_panorama\_attachment) | A object defining TGW attachment and CIDR for Panorama.

Following properties are available:
- `tgw_key`: key of the TGW for Panorama attachment
- `transit_gateway_attachment_id`: ID of attachment for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
tgw\_key = "tgw"
transit\_gateway\_attachment\_id = "tgw-attach-123456789"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
tgw\_key = string
transit\_gateway\_attachment\_id = string
vpc\_cidr = string
})
|
{
"tgw\_key": "tgw",
"transit\_gateway\_attachment\_id": null,
"vpc\_cidr": "10.255.0.0/24"
}
| no | | [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | -| [spoke\_lbs](#input\_spoke\_lbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
vpc = string
subnet\_group = string
vms = list(string)
}))
| `{}` | no | -| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 type VM

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t2.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = string
}))
| `{}` | no | -| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | -| [tgw](#input\_tgw) | A object defining Transit Gateway.

Following properties are available:
- `create`: set to false, if existing TGW needs to be reused
- `id`: id of existing TGW or null
- `name`: name of TGW to create or use
- `asn`: ASN number
- `route_tables`: map of route tables
- `attachments`: map of TGW attachments

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route\_tables = {
"from\_security\_vpc" = {
create = true
name = "from\_security"
}
}
attachments = {
security = {
name = "vmseries"
vpc = "security\_vpc"
subnet\_group = "tgw\_attach"
route\_table = "from\_security\_vpc"
propagate\_routes\_to = ["from\_spoke\_vpc"]
}
}
}
|
object({
create = bool
id = string
name = string
asn = string
route\_tables = map(object({
create = bool
name = string
}))
attachments = map(object({
name = string
vpc = string
subnet\_group = string
route\_table = string
propagate\_routes\_to = list(string)
}))
})
| n/a | yes | -| [vmseries](#input\_vmseries) | A 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
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces

Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
"02" = { az = "eu-central-1b" }
}

# 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"

# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security\_gwlb"

interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
vpc = "security\_vpc"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
vpc = "security\_vpc"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
vpc = "security\_vpc"
subnet\_group = "public"
create\_public\_ip = true
source\_dest\_check = false
}
}

# Value of `gwlb\_endpoint` must match key of objects stored in `gwlb\_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

system\_services = {
dns\_primary = "4.2.2.2" # TODO: update here
dns\_secondy = null # TODO: update here
ntp\_primary = "pool.ntp.org" # TODO: update here
ntp\_secondy = null # TODO: update here
}

application\_lb = null
network\_lb = null
}
}
|
map(object({
instances = map(object({
az = string
}))

bootstrap\_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = string
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos\_version = string
ebs\_kms\_id = string

vpc = string
gwlb = string

interfaces = map(object({
device\_index = number
security\_group = string
vpc = string
subnet\_group = string
create\_public\_ip = bool
source\_dest\_check = bool
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

system\_services = object({
dns\_primary = string
dns\_secondy = string
ntp\_primary = string
ntp\_secondy = string
})

application\_lb = object({
name = string
subnet\_group = string
security\_group = string
rules = any
})

network\_lb = object({
name = string
subnet\_group = string
rules = any
})
}))
| `{}` | no | -| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet\_group` - key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "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
subnet\_group = string
nacl = string
}))
routes = map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
}))
}))
| `{}` | no | +| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = map(object({
protocol = optional(string, "HTTP")
port = optional(number, 80)
health\_check\_port = optional(string, "80")
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
health\_check\_interval = optional(number, 10)
listener\_rules = map(object({
target\_protocol = string
target\_port = number
path\_pattern = list(string)
}))
}))
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| `{}` | no | +| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `name`: Name of the NLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs
- `internal_lb`(optional): flag to switch between internet\_facing and internal NLB
- `balance_rules` (optional): Rules defining the method of traffic balancing

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
vms = list(string)
internal\_lb = optional(bool, false)
balance\_rules = map(object({
protocol = string
port = string
stickiness = optional(bool, true)
}))
}))
| `{}` | no | +| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 VM type

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t3.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = optional(string, "t3.micro")
}))
| `{}` | no | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | `""` | no | +| [tgw\_attachments](#input\_tgw\_attachments) | A object defining Transit Gateway Attachments.

Following properties are available:
- `tgw_key`: key of the TGW to be attached
- `create`: set to false, if existing TGW attachment needs to be reused
- `id`: id of existing TGW
- `security_vpc_attachment`: set to true if default route from spoke VPCs towards
this attachment should be created
- `name`: name of the TGW attachment to create or use
- `asn`: ASN number
- `vpc`: key of the attaching VPC
- `route_table`: route table key created under TGW taht must be associated with attachment
- `propagate_routes_to`: route table key created under TGW

Example:
tgw\_attachments = {
security = {
tgw\_key = "tgw"
name = "vmseries"
vpc = "security\_vpc"
subnet\_group = "tgw\_attach"
route\_table = "from\_security\_vpc"
propagate\_routes\_to = "from\_spoke\_vpc"
}
}
|
map(object({
tgw\_key = string
create = optional(bool, true)
id = optional(string)
security\_vpc\_attachment = optional(bool, false)
name = string
vpc = string
subnet\_group = string
route\_table = string
propagate\_routes\_to = string
appliance\_mode\_support = optional(string, "enable")
dns\_support = optional(string, null)
tags = optional(map(string))
}))
| `{}` | no | +| [tgws](#input\_tgws) | A object defining Transit Gateway.

Following properties are available:
- `create`: set to false, if existing TGW needs to be reused
- `id`: id of existing TGW
- `name`: name of TGW to create or use
- `asn`: ASN number
- `route_tables`: map of route tables

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route\_tables = {
"from\_security\_vpc" = {
create = true
name = "from\_security"
}
}
}
|
map(object({
create = optional(bool, true)
id = optional(string)
name = string
asn = string
route\_tables = map(object({
create = bool
name = string
}))
}))
| `{}` | no | +| [vmseries](#input\_vmseries) | A 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
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces

Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
"02" = { az = "eu-central-1b" }
}

# 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"

# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security\_gwlb"

interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
vpc = "security\_vpc"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
vpc = "security\_vpc"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
vpc = "security\_vpc"
subnet\_group = "public"
create\_public\_ip = true
source\_dest\_check = false
}
}

# Value of `gwlb\_endpoint` must match key of objects stored in `gwlb\_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

system\_services = {
dns\_primary = "4.2.2.2" # TODO: update here
dns\_secondy = null # TODO: update here
ntp\_primary = "pool.ntp.org" # TODO: update here
ntp\_secondy = null # TODO: update here
}
}
}
|
map(object({
instances = map(object({
az = string
name = optional(string)
}))

bootstrap\_options = object({
hostname = optional(string)
mgmt-interface-swap = string
plugin-op-commands = string
op-command-modes = optional(string)
panorama-server = string
panorama-server-2 = optional(string)
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
cgname = optional(string)
dns-primary = optional(string)
dns-secondary = optional(string)
dhcp-send-hostname = optional(string)
dhcp-send-client-id = optional(string)
dhcp-accept-server-hostname = optional(string)
dhcp-accept-server-domain = optional(string)
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos\_version = string
vmseries\_ami\_id = optional(string)
vmseries\_product\_code = optional(string, "6njl1pau431dv1qxipg63mvah")
include\_deprecated\_ami = optional(bool, false)
instance\_type = optional(string, "m5.xlarge")
ebs\_encrypted = optional(bool, true)
ebs\_kms\_id = optional(string, "alias/aws/ebs")
enable\_instance\_termination\_protection = optional(bool, false)
enable\_monitoring = optional(bool, false)
fw\_license\_type = optional(string, "byol")

vpc = string
gwlb = optional(string)

interfaces = map(object({
device\_index = number
name = optional(string)
description = optional(string)
security\_group = string
subnet\_group = string
create\_public\_ip = optional(bool, false)
eip\_allocation\_id = optional(string)
source\_dest\_check = optional(bool, false)
private\_ips = optional(list(string))
ipv6\_address\_count = optional(number, null)
public\_ipv4\_pool = optional(string)
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

tags = optional(map(string))

system\_services = object({
dns\_primary = string
dns\_secondy = optional(string)
ntp\_primary = string
ntp\_secondy = optional(string)
})

application\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
security\_group = optional(string)
rules = optional(any)
}), {})

network\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
rules = optional(any)
}), {})
}))
| `{}` | no | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | ### Outputs | Name | Description | |------|-------------| -| [app\_inspected\_dns\_name](#output\_app\_inspected\_dns\_name) | FQDN of App Internal Load Balancer.
Can be used in VM-Series configuration to balance traffic between the application instances. | +| [application\_load\_balancers](#output\_application\_load\_balancers) | FQDNs of Application Load Balancers | +| [network\_load\_balancers](#output\_network\_load\_balancers) | FQDNs of Network Load Balancers. | | [public\_alb\_dns\_name](#output\_public\_alb\_dns\_name) | FQDN of VM-Series External Application Load Balancer used in centralized design. | | [public\_nlb\_dns\_name](#output\_public\_nlb\_dns\_name) | FQDN of VM-Series External Network Load Balancer used in centralized design. | | [vmseries\_public\_ips](#output\_vmseries\_public\_ips) | Map of public IPs created within `vmseries` module instances. | diff --git a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/centralized_design_autoscale.md b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/centralized_design_autoscale.md index 156c72c97..73c3bbe29 100644 --- a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/centralized_design_autoscale.md +++ b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/centralized_design_autoscale.md @@ -172,7 +172,8 @@ statistic = "Maximum" | Name | Source | Version | |------|--------|---------| -| [app\_lb](#module\_app\_lb) | ../../modules/nlb | n/a | +| [app\_alb](#module\_app\_alb) | ../../modules/alb | n/a | +| [app\_nlb](#module\_app\_nlb) | ../../modules/nlb | n/a | | [gwlb](#module\_gwlb) | ../../modules/gwlb | n/a | | [gwlbe\_endpoint](#module\_gwlbe\_endpoint) | ../../modules/gwlb_endpoint_set | n/a | | [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | @@ -209,24 +210,27 @@ statistic = "Maximum" | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `any` | n/a | yes | -| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `gwlb`: key of GWLB
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
gwlb = string
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
}))
| `{}` | no | -| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
}))
| `{}` | no | +| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `custom_names`: Optional map of names of the VPC Endpoints, used to override the default naming generated from the input `name`.
Each key is the Availability Zone identifier, for example `us-east-1b`.
- `gwlb`: key of GWLB. Required when GWLB Endpoint must connect to GWLB's service name
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint
- `cloudngfw_key`(optional): Key of the Cloud NGFW. Required when GWLB Endpoint must connect to Cloud NGFW's service name

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
custom\_names = optional(map(string), {})
gwlb = optional(string)
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
delay = optional(number, 0)
tags = optional(map(string))
cloudngfw\_key = optional(string)
}))
| `{}` | no | +| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
tg\_name = optional(string)
target\_instances = optional(map(object({
id = string
})), {})
acceptance\_required = optional(bool, false)
allowed\_principals = optional(list(string), [])
deregistration\_delay = optional(number)
health\_check\_enabled = optional(bool)
health\_check\_interval = optional(number, 5)
health\_check\_matcher = optional(string)
health\_check\_path = optional(string)
health\_check\_port = optional(number, 80)
health\_check\_protocol = optional(string)
health\_check\_timeout = optional(number)
healthy\_threshold = optional(number, 3)
unhealthy\_threshold = optional(number, 3)
stickiness\_type = optional(string)
rebalance\_flows = optional(string, "no\_rebalance")
lb\_tags = optional(map(string), {})
lb\_target\_group\_tags = optional(map(string), {})
endpoint\_service\_tags = optional(map(string), {})
enable\_lb\_deletion\_protection = optional(bool)
}))
| `{}` | no | | [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | n/a | yes | -| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `name`: name of NAT Gateway
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
natgws = {
security\_nat\_gw = {
name = "natgw"
vpc = "security\_vpc"
subnet\_group = "natgw"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
}))
| `{}` | no | -| [panorama\_attachment](#input\_panorama\_attachment) | A object defining TGW attachment and CIDR for Panorama.

Following properties are available:
- `transit_gateway_attachment_id`: ID of attachment for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
transit\_gateway\_attachment\_id = "tgw-attach-123456789"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
transit\_gateway\_attachment\_id = string
vpc\_cidr = string
})
| `null` | no | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | +| [panorama\_attachment](#input\_panorama\_attachment) | A object defining TGW attachment and CIDR for Panorama.

Following properties are available:
- `tgw_key`: key of the TGW for Panorama attachment
- `transit_gateway_attachment_id`: ID of attachment for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
tgw\_key = "tgw"
transit\_gateway\_attachment\_id = "tgw-attach-123456789"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
tgw\_key = string
transit\_gateway\_attachment\_id = string
vpc\_cidr = string
})
|
{
"tgw\_key": "tgw",
"transit\_gateway\_attachment\_id": null,
"vpc\_cidr": "10.255.0.0/24"
}
| no | | [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | -| [spoke\_lbs](#input\_spoke\_lbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
vpc = string
subnet\_group = string
vms = list(string)
}))
| `{}` | no | -| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 type VM

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t2.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = string
}))
| `{}` | no | -| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | -| [tgw](#input\_tgw) | A object defining Transit Gateway.

Following properties are available:
- `create`: set to false, if existing TGW needs to be reused
- `id`: id of existing TGW or null
- `name`: name of TGW to create or use
- `asn`: ASN number
- `route_tables`: map of route tables
- `attachments`: map of TGW attachments

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route\_tables = {
"from\_security\_vpc" = {
create = true
name = "from\_security"
}
}
attachments = {
security = {
name = "vmseries"
vpc = "security\_vpc"
subnet\_group = "tgw\_attach"
route\_table = "from\_security\_vpc"
propagate\_routes\_to = ["from\_spoke\_vpc"]
}
}
}
|
object({
create = bool
id = string
name = string
asn = string
route\_tables = map(object({
create = bool
name = string
}))
attachments = map(object({
name = string
vpc = string
subnet\_group = string
route\_table = string
propagate\_routes\_to = list(string)
}))
})
| n/a | yes | -| [vmseries\_asgs](#input\_vmseries\_asgs) | A map defining Autoscaling Groups with VM-Series instances.

Following properties are available:
- `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
- `gwlb`: key of GWLB
- `zones`: zones for the Autoscaling Group to be built in
- `interfaces`: configuration of network interfaces for VM-Series used by Lamdba while provisioning new VM-Series in autoscaling group
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `asg`: the number of Amazon EC2 instances that should be running in the group (desired, minimum, maximum)
- `scaling_plan`: scaling plan with attributes
- `enabled`: `true` if automatic dynamic scaling policy should be created
- `metric_name`: name of the metric used in dynamic scaling policy
- `estimated_instance_warmup`: estimated time, in seconds, until a newly launched instance can contribute to the CloudWatch metrics
- `target_value`: target value for the metric used in dynamic scaling policy
- `statistic`: statistic of the metric. Valid values: Average, Maximum, Minimum, SampleCount, Sum
- `cloudwatch_namespace`: name of CloudWatch namespace, where metrics are available (it should be the same as namespace configured in VM-Series plugin in PAN-OS)
- `tags`: tags configured for dynamic scaling policy
- `launch_template_version`: launch template version to use to launch instances
- `instance_refresh`: instance refresh for ASG defined by several attributes (please see README for module `asg` for more details)

Example:
vmseries\_asgs = {
main\_asg = {
bootstrap\_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable" # TODO: update here
panorama-server = "" # TODO: update here
auth-key = "" # TODO: update here
dgname = "" # TODO: update here
tplname = "" # TODO: update here
dhcp-send-hostname = "yes" # TODO: update here
dhcp-send-client-id = "yes" # TODO: update here
dhcp-accept-server-hostname = "yes" # TODO: update here
dhcp-accept-server-domain = "yes" # TODO: update here
}

panos\_version = "10.2.3" # TODO: update here
ebs\_kms\_id = "alias/aws/ebs" # TODO: update here

vpc = "security\_vpc"
gwlb = "security\_gwlb"

zones = {
"01" = "us-west-1a"
"02" = "us-west-1b"
}

interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
subnet\_group = "public"
create\_public\_ip = false
source\_dest\_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired\_cap = 0
min\_size = 0
max\_size = 4
lambda\_execute\_pip\_install\_once = true
}

scaling\_plan = {
enabled = true
metric\_name = "panSessionActive"
estimated\_instance\_warmup = 900
target\_value = 75
statistic = "Average"
cloudwatch\_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch\_template\_version = "1"

instance\_refresh = {
strategy = "Rolling"
preferences = {
checkpoint\_delay = 3600
checkpoint\_percentages = [50, 100]
instance\_warmup = 1200
min\_healthy\_percentage = 50
skip\_matching = false
auto\_rollback = false
scale\_in\_protected\_instances = "Ignore"
standby\_instances = "Ignore"
}
triggers = []
}

application\_lb = null
network\_lb = null
}
}
|
map(object({
bootstrap\_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = string
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos\_version = string
ebs\_kms\_id = string

vpc = string
gwlb = string

zones = map(any)

interfaces = map(object({
device\_index = number
security\_group = string
subnet\_group = string
create\_public\_ip = bool
source\_dest\_check = bool
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

asg = object({
desired\_cap = number
min\_size = number
max\_size = number
lambda\_execute\_pip\_install\_once = bool
})

scaling\_plan = object({
enabled = bool
metric\_name = string
estimated\_instance\_warmup = number
target\_value = number
statistic = string
cloudwatch\_namespace = string
tags = map(string)
})

launch\_template\_version = string

instance\_refresh = object({
strategy = string
preferences = object({
checkpoint\_delay = number
checkpoint\_percentages = list(number)
instance\_warmup = number
min\_healthy\_percentage = number
skip\_matching = bool
auto\_rollback = bool
scale\_in\_protected\_instances = string
standby\_instances = string
})
triggers = list(string)
})

application\_lb = object({
name = string
subnet\_group = string
security\_group = string
rules = any
})

network\_lb = object({
name = string
subnet\_group = string
rules = any
})
}))
| `{}` | no | -| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet\_group` - key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "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
subnet\_group = string
nacl = string
}))
routes = map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
}))
}))
| `{}` | no | +| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = map(object({
protocol = optional(string, "HTTP")
port = optional(number, 80)
health\_check\_port = optional(string, "80")
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
health\_check\_interval = optional(number, 10)
listener\_rules = map(object({
target\_protocol = string
target\_port = number
path\_pattern = list(string)
}))
}))
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| `{}` | no | +| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `name`: Name of the NLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs
- `internal_lb`(optional): flag to switch between internet\_facing and internal NLB
- `balance_rules` (optional): Rules defining the method of traffic balancing

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
vms = list(string)
internal\_lb = optional(bool, false)
balance\_rules = map(object({
protocol = string
port = string
stickiness = optional(bool, true)
}))
}))
| `{}` | no | +| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 VM type

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t3.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = optional(string, "t3.micro")
}))
| `{}` | no | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | `""` | no | +| [tgw\_attachments](#input\_tgw\_attachments) | A object defining Transit Gateway Attachments.

Following properties are available:
- `tgw_key`: key of the TGW to be attached
- `create`: set to false, if existing TGW attachment needs to be reused
- `id`: id of existing TGW
- `security_vpc_attachment`: set to true if default route from spoke VPCs towards
this attachment should be created
- `name`: name of the TGW attachment to create or use
- `asn`: ASN number
- `vpc`: key of the attaching VPC
- `route_table`: route table key created under TGW taht must be associated with attachment
- `propagate_routes_to`: route table key created under TGW

Example:
tgw\_attachments = {
security = {
tgw\_key = "tgw"
name = "vmseries"
vpc = "security\_vpc"
subnet\_group = "tgw\_attach"
route\_table = "from\_security\_vpc"
propagate\_routes\_to = "from\_spoke\_vpc"
}
}
|
map(object({
tgw\_key = string
create = optional(bool, true)
id = optional(string)
security\_vpc\_attachment = optional(bool, false)
name = string
vpc = string
subnet\_group = string
route\_table = string
propagate\_routes\_to = string
appliance\_mode\_support = optional(string, "enable")
dns\_support = optional(string, null)
tags = optional(map(string))
}))
| `{}` | no | +| [tgws](#input\_tgws) | A object defining Transit Gateway.

Following properties are available:
- `create`: set to false, if existing TGW needs to be reused
- `id`: id of existing TGW
- `name`: name of TGW to create or use
- `asn`: ASN number
- `route_tables`: map of route tables

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route\_tables = {
"from\_security\_vpc" = {
create = true
name = "from\_security"
}
}
}
|
map(object({
create = optional(bool, true)
id = optional(string)
name = string
asn = string
route\_tables = map(object({
create = bool
name = string
}))
}))
| `{}` | no | +| [vmseries\_asgs](#input\_vmseries\_asgs) | A map defining Autoscaling Groups with VM-Series instances.

Following properties are available:
- `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
- `gwlb`: key of GWLB
- `zones`: zones for the Autoscaling Group to be built in
- `interfaces`: configuration of network interfaces for VM-Series used by Lamdba while provisioning new VM-Series in autoscaling group
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `asg`: the number of Amazon EC2 instances that should be running in the group (desired, minimum, maximum)
- `scaling_plan`: scaling plan with attributes
- `enabled`: `true` if automatic dynamic scaling policy should be created
- `metric_name`: name of the metric used in dynamic scaling policy
- `estimated_instance_warmup`: estimated time, in seconds, until a newly launched instance can contribute to the CloudWatch metrics
- `target_value`: target value for the metric used in dynamic scaling policy
- `statistic`: statistic of the metric. Valid values: Average, Maximum, Minimum, SampleCount, Sum
- `cloudwatch_namespace`: name of CloudWatch namespace, where metrics are available (it should be the same as namespace configured in VM-Series plugin in PAN-OS)
- `tags`: tags configured for dynamic scaling policy
- `launch_template_version`: launch template version to use to launch instances
- `instance_refresh`: instance refresh for ASG defined by several attributes (please see README for module `asg` for more details)

Example:
vmseries\_asgs = {
main\_asg = {
bootstrap\_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable" # TODO: update here
panorama-server = "" # TODO: update here
auth-key = "" # TODO: update here
dgname = "" # TODO: update here
tplname = "" # TODO: update here
dhcp-send-hostname = "yes" # TODO: update here
dhcp-send-client-id = "yes" # TODO: update here
dhcp-accept-server-hostname = "yes" # TODO: update here
dhcp-accept-server-domain = "yes" # TODO: update here
}

panos\_version = "10.2.3" # TODO: update here
ebs\_kms\_id = "alias/aws/ebs" # TODO: update here

vpc = "security\_vpc"
gwlb = "security\_gwlb"

zones = {
"01" = "us-west-1a"
"02" = "us-west-1b"
}

interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
subnet\_group = "public"
create\_public\_ip = false
source\_dest\_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired\_cap = 0
min\_size = 0
max\_size = 4
lambda\_execute\_pip\_install\_once = true
}

scaling\_plan = {
enabled = true
metric\_name = "panSessionActive"
estimated\_instance\_warmup = 900
target\_value = 75
statistic = "Average"
cloudwatch\_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch\_template\_version = "1"

instance\_refresh = {
strategy = "Rolling"
preferences = {
checkpoint\_delay = 3600
checkpoint\_percentages = [50, 100]
instance\_warmup = 1200
min\_healthy\_percentage = 50
skip\_matching = false
auto\_rollback = false
scale\_in\_protected\_instances = "Ignore"
standby\_instances = "Ignore"
}
triggers = []
}
}
}
|
map(object({
bootstrap\_options = object({
hostname = optional(string)
mgmt-interface-swap = string
plugin-op-commands = string
op-command-modes = optional(string)
panorama-server = string
panorama-server-2 = optional(string)
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
cgname = optional(string)
dns-primary = optional(string)
dns-secondary = optional(string)
dhcp-send-hostname = optional(string)
dhcp-send-client-id = optional(string)
dhcp-accept-server-hostname = optional(string)
dhcp-accept-server-domain = optional(string)
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos\_version = string
vmseries\_ami\_id = optional(string)
vmseries\_product\_code = optional(string, "6njl1pau431dv1qxipg63mvah")
include\_deprecated\_ami = optional(bool, false)
instance\_type = optional(string, "m5.xlarge")
ebs\_encrypted = optional(bool, true)
ebs\_kms\_id = optional(string, "alias/aws/ebs")
enable\_instance\_termination\_protection = optional(bool, false)
enable\_monitoring = optional(bool, false)
fw\_license\_type = optional(string, "byol")


vpc = string
gwlb = optional(string)

zones = map(any)

interfaces = map(object({
device\_index = number
security\_group = string
subnet\_group = string
create\_public\_ip = optional(bool, false)
source\_dest\_check = bool
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

lambda\_timeout = optional(number, 30)
delicense\_ssm\_param\_name = optional(string)
delicense\_enabled = optional(bool, false)
reserved\_concurrent\_executions = optional(number, 100)
asg\_name = optional(string, "asg")
asg = object({
desired\_cap = optional(number, 2)
min\_size = optional(number, 1)
max\_size = optional(number, 2)
lambda\_execute\_pip\_install\_once = optional(bool, false)
lifecycle\_hook\_timeout = optional(number, 300)
health\_check = optional(object({
grace\_period = number
type = string
}), {
grace\_period = 300
type = "EC2"
})
delete\_timeout = optional(string, "20m")
suspended\_processes = optional(list(string), [])
})

scaling\_plan = object({
enabled = optional(bool, false)
metric\_name = optional(string, "")
estimated\_instance\_warmup = optional(number, 900)
target\_value = optional(number, 70)
statistic = optional(string, "Average")
cloudwatch\_namespace = optional(string, "VMseries\_dimensions")
tags = map(string)
})

launch\_template\_update\_default\_version = optional(bool, true)
launch\_template\_version = optional(string, "$Latest")
tag\_specifications\_targets = optional(list(string), ["instance", "volume", "network-interface"])

instance\_refresh = optional(object({
strategy = string
preferences = object({
checkpoint\_delay = number
checkpoint\_percentages = list(number)
instance\_warmup = number
min\_healthy\_percentage = number
skip\_matching = bool
auto\_rollback = bool
scale\_in\_protected\_instances = string
standby\_instances = string
})
triggers = list(string)
}), null)

application\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
security\_group = optional(string)
rules = optional(any)
}), {})

network\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
rules = optional(any)
}), {})
}))
| `{}` | no | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | ### Outputs | Name | Description | |------|-------------| -| [app\_inspected\_dns\_name](#output\_app\_inspected\_dns\_name) | FQDN of App Internal Load Balancer.
Can be used in VM-Series configuration to balance traffic between the application instances. | +| [application\_load\_balancers](#output\_application\_load\_balancers) | FQDNs of Application Load Balancers | +| [network\_load\_balancers](#output\_network\_load\_balancers) | FQDNs of Network Load Balancers. | | [public\_alb\_dns\_name](#output\_public\_alb\_dns\_name) | FQDN of VM-Series External Application Load Balancer used in centralized design. | | [public\_nlb\_dns\_name](#output\_public\_nlb\_dns\_name) | FQDN of VM-Series External Network Load Balancer used in centralized design. | \ No newline at end of file diff --git a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/combined_design.md b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/combined_design.md index 053f1af86..3540c659e 100644 --- a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/combined_design.md +++ b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/combined_design.md @@ -93,6 +93,9 @@ To cleanup the infrastructure run: terraform destroy ``` +Note: +To deploy the Prisma AIRS product, uncomment the designated (airs_deployment = true) line in the terraform.tfvars file. + ## Traffic Validation If no errors occurred during deployment, configure the VM-Series machines as expected. @@ -105,7 +108,7 @@ If no errors occurred during deployment, configure the VM-Series machines as exp - Make sure GWLB sees all VM-Series in the target group as healthy - Take the ALB address and see if we are able to get the welcome page from the test app - Make sure all traffic is visible in the monitor tab in VM-Series (check if the traffic works as expected, if it goes to the right policies) -- + ## Reference ### Requirements @@ -125,11 +128,11 @@ If no errors occurred during deployment, configure the VM-Series machines as exp | Name | Source | Version | |------|--------|---------| +| [app\_alb](#module\_app\_alb) | ../../modules/alb | n/a | +| [app\_nlb](#module\_app\_nlb) | ../../modules/nlb | n/a | | [gwlb](#module\_gwlb) | ../../modules/gwlb | n/a | | [gwlbe\_endpoint](#module\_gwlbe\_endpoint) | ../../modules/gwlb_endpoint_set | n/a | | [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | -| [public\_alb](#module\_public\_alb) | ../../modules/alb | n/a | -| [public\_nlb](#module\_public\_nlb) | ../../modules/nlb | n/a | | [subnet\_sets](#module\_subnet\_sets) | ../../modules/subnet_set | n/a | | [transit\_gateway](#module\_transit\_gateway) | ../../modules/transit_gateway | n/a | | [transit\_gateway\_attachment](#module\_transit\_gateway\_attachment) | ../../modules/transit_gateway_attachment | n/a | @@ -162,19 +165,20 @@ If no errors occurred during deployment, configure the VM-Series machines as exp | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `any` | n/a | yes | -| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `gwlb`: key of GWLB
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
gwlb = string
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
}))
| `{}` | no | -| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
}))
| `{}` | no | +| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `custom_names`: Optional map of names of the VPC Endpoints, used to override the default naming generated from the input `name`.
Each key is the Availability Zone identifier, for example `us-east-1b`.
- `gwlb`: key of GWLB. Required when GWLB Endpoint must connect to GWLB's service name
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint
- `cloudngfw_key`(optional): Key of the Cloud NGFW. Required when GWLB Endpoint must connect to Cloud NGFW's service name

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
custom\_names = optional(map(string), {})
gwlb = optional(string)
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
delay = optional(number, 0)
tags = optional(map(string))
cloudngfw\_key = optional(string)
}))
| `{}` | no | +| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
tg\_name = optional(string)
target\_instances = optional(map(object({
id = string
})), {})
acceptance\_required = optional(bool, false)
allowed\_principals = optional(list(string), [])
deregistration\_delay = optional(number)
health\_check\_enabled = optional(bool)
health\_check\_interval = optional(number, 5)
health\_check\_matcher = optional(string)
health\_check\_path = optional(string)
health\_check\_port = optional(number, 80)
health\_check\_protocol = optional(string)
health\_check\_timeout = optional(number)
healthy\_threshold = optional(number, 3)
unhealthy\_threshold = optional(number, 3)
stickiness\_type = optional(string)
rebalance\_flows = optional(string, "no\_rebalance")
lb\_tags = optional(map(string), {})
lb\_target\_group\_tags = optional(map(string), {})
endpoint\_service\_tags = optional(map(string), {})
enable\_lb\_deletion\_protection = optional(bool)
}))
| `{}` | no | | [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | n/a | yes | -| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `name`: name of NAT Gateway
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
natgws = {
security\_nat\_gw = {
name = "natgw"
vpc = "security\_vpc"
subnet\_group = "natgw"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
}))
| `{}` | no | -| [panorama\_attachment](#input\_panorama\_attachment) | An object defining TGW attachment and CIDR for Panorama.


Following properties are available:
- `transit_gateway_attachment_id`: ID of attachment for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
transit\_gateway\_attachment\_id = "tgw-attach-123456789"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
transit\_gateway\_attachment\_id = string
vpc\_cidr = string
})
| `null` | no | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | +| [panorama\_attachment](#input\_panorama\_attachment) | A object defining TGW attachment and CIDR for Panorama.

Following properties are available:
- `tgw_key`: key of the TGW for Panorama attachment
- `transit_gateway_attachment_id`: ID of attachment for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
tgw\_key = "tgw"
transit\_gateway\_attachment\_id = "tgw-attach-123456789"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
tgw\_key = string
transit\_gateway\_attachment\_id = string
vpc\_cidr = string
})
|
{
"tgw\_key": "tgw",
"transit\_gateway\_attachment\_id": null,
"vpc\_cidr": "10.255.0.0/24"
}
| no | | [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | -| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnet\_groups in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = any
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| n/a | yes | -| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
vpc = string
subnet\_group = string
vms = list(string)
}))
| `{}` | no | -| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 type VM

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t2.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = string
}))
| `{}` | no | -| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | -| [tgw](#input\_tgw) | A object defining Transit Gateway.

Following properties are available:
- `create`: set to false, if existing TGW needs to be reused
- `id`: id of existing TGW or null
- `name`: name of TGW to create or use
- `asn`: ASN number
- `route_tables`: map of route tables
- `attachments`: map of TGW attachments

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route\_tables = {
"from\_security\_vpc" = {
create = true
name = "from\_security"
}
}
attachments = {
security = {
name = "vmseries"
vpc = "security\_vpc"
subnet\_group = "tgw\_attach"
route\_table = "from\_security\_vpc"
propagate\_routes\_to = ["from\_spoke\_vpc"]
}
}
}
|
object({
create = bool
id = string
name = string
asn = string
route\_tables = map(object({
create = bool
name = string
}))
attachments = map(object({
name = string
vpc = string
subnet\_group = string
route\_table = string
propagate\_routes\_to = list(string)
}))
})
| n/a | yes | -| [vmseries](#input\_vmseries) | A 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
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces
Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
"02" = { az = "eu-central-1b" }
}
# 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"
# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security\_gwlb"
interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
vpc = "security\_vpc"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
vpc = "security\_vpc"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
vpc = "security\_vpc"
subnet\_group = "public"
create\_public\_ip = true
source\_dest\_check = false
}
}
# Value of `gwlb\_endpoint` must match key of objects stored in `gwlb\_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}
system\_services = {
dns\_primary = "4.2.2.2" # TODO: update here
dns\_secondy = null # TODO: update here
ntp\_primary = "pool.ntp.org" # TODO: update here
ntp\_secondy = null # TODO: update here
}
application\_lb = null
network\_lb = null
}
}
|
map(object({
instances = map(object({
az = string
}))

bootstrap\_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = string
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos\_version = string
ebs\_kms\_id = string

vpc = string
gwlb = string

interfaces = map(object({
device\_index = number
security\_group = string
vpc = string
subnet\_group = string
create\_public\_ip = bool
source\_dest\_check = bool
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

system\_services = object({
dns\_primary = string
dns\_secondy = string
ntp\_primary = string
ntp\_secondy = string
})

application\_lb = object({
name = string
rules = any
})

network\_lb = object({
name = string
rules = any
})
}))
| `{}` | no | -| [vpcs](#input\_vpcs) | A 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
- `subnet_group`: identity of the same purpose subnets group such as management
- `nacl`: key of NACL (can be null)
- `routes`: map of routes with properties:
- `vpc` - VPC key
- `subnet_group` - subnet\_group key
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "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 = 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 | +| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = map(object({
protocol = optional(string, "HTTP")
port = optional(number, 80)
health\_check\_port = optional(string, "80")
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
health\_check\_interval = optional(number, 10)
listener\_rules = map(object({
target\_protocol = string
target\_port = number
path\_pattern = list(string)
}))
}))
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| `{}` | no | +| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `name`: Name of the NLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs
- `internal_lb`(optional): flag to switch between internet\_facing and internal NLB
- `balance_rules` (optional): Rules defining the method of traffic balancing

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
vms = list(string)
internal\_lb = optional(bool, false)
balance\_rules = map(object({
protocol = string
port = string
stickiness = optional(bool, true)
}))
}))
| `{}` | no | +| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 VM type

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t3.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = optional(string, "t3.micro")
}))
| `{}` | no | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | `""` | no | +| [tgw\_attachments](#input\_tgw\_attachments) | A object defining Transit Gateway Attachments.

Following properties are available:
- `tgw_key`: key of the TGW to be attached
- `create`: set to false, if existing TGW attachment needs to be reused
- `id`: id of existing TGW
- `security_vpc_attachment`: set to true if default route from spoke VPCs towards
this attachment should be created
- `name`: name of the TGW attachment to create or use
- `asn`: ASN number
- `vpc`: key of the attaching VPC
- `route_table`: route table key created under TGW taht must be associated with attachment
- `propagate_routes_to`: route table key created under TGW

Example:
tgw\_attachments = {
security = {
tgw\_key = "tgw"
name = "vmseries"
vpc = "security\_vpc"
subnet\_group = "tgw\_attach"
route\_table = "from\_security\_vpc"
propagate\_routes\_to = "from\_spoke\_vpc"
}
}
|
map(object({
tgw\_key = string
create = optional(bool, true)
id = optional(string)
security\_vpc\_attachment = optional(bool, false)
name = string
vpc = string
subnet\_group = string
route\_table = string
propagate\_routes\_to = string
appliance\_mode\_support = optional(string, "enable")
dns\_support = optional(string, null)
tags = optional(map(string))
}))
| `{}` | no | +| [tgws](#input\_tgws) | A object defining Transit Gateway.

Following properties are available:
- `create`: set to false, if existing TGW needs to be reused
- `id`: id of existing TGW
- `name`: name of TGW to create or use
- `asn`: ASN number
- `route_tables`: map of route tables

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route\_tables = {
"from\_security\_vpc" = {
create = true
name = "from\_security"
}
}
}
|
map(object({
create = optional(bool, true)
id = optional(string)
name = string
asn = string
route\_tables = map(object({
create = bool
name = string
}))
}))
| `{}` | no | +| [vmseries](#input\_vmseries) | A 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
- `airs_deployment (optional|false)`: flag to deploy AIRS product type
- `ebs_kms_id`: alias for AWS KMS used for EBS encryption in VM-Series
- `vpc`: key of VPC
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces

Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
"02" = { az = "eu-central-1b" }
}

# 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"

# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security\_gwlb"

interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
vpc = "security\_vpc"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
vpc = "security\_vpc"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
vpc = "security\_vpc"
subnet\_group = "public"
create\_public\_ip = true
source\_dest\_check = false
}
}

# Value of `gwlb\_endpoint` must match key of objects stored in `gwlb\_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

system\_services = {
dns\_primary = "4.2.2.2" # TODO: update here
dns\_secondy = null # TODO: update here
ntp\_primary = "pool.ntp.org" # TODO: update here
ntp\_secondy = null # TODO: update here
}
}
}
|
map(object({
instances = map(object({
az = string
name = optional(string)
}))

bootstrap\_options = object({
hostname = optional(string)
mgmt-interface-swap = string
plugin-op-commands = string
op-command-modes = optional(string)
panorama-server = string
panorama-server-2 = optional(string)
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
cgname = optional(string)
dns-primary = optional(string)
dns-secondary = optional(string)
dhcp-send-hostname = optional(string)
dhcp-send-client-id = optional(string)
dhcp-accept-server-hostname = optional(string)
dhcp-accept-server-domain = optional(string)
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos\_version = string
airs\_deployment = optional(bool, false)
ebs\_kms\_id = string
vmseries\_ami\_id = optional(string)
vmseries\_product\_code = optional(string, "6njl1pau431dv1qxipg63mvah")
include\_deprecated\_ami = optional(bool, false)
instance\_type = optional(string, "m5.xlarge")
ebs\_encrypted = optional(bool, true)
enable\_instance\_termination\_protection = optional(bool, false)
enable\_monitoring = optional(bool, false)
fw\_license\_type = optional(string, "byol")

vpc = string
gwlb = optional(string)

interfaces = map(object({
device\_index = number
name = optional(string)
description = optional(string)
security\_group = string
subnet\_group = string
create\_public\_ip = optional(bool, false)
eip\_allocation\_id = optional(string)
source\_dest\_check = optional(bool, false)
private\_ips = optional(list(string))
ipv6\_address\_count = optional(number, null)
public\_ipv4\_pool = optional(string)
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

tags = optional(map(string))

system\_services = object({
dns\_primary = string
dns\_secondy = optional(string)
ntp\_primary = string
ntp\_secondy = optional(string)
})

application\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
security\_group = optional(string)
rules = optional(any)
}), {})

network\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
rules = optional(any)
}), {})
}))
| `{}` | no | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | ### Outputs diff --git a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/combined_design_autoscale.md b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/combined_design_autoscale.md index 50b2c2505..87ec90dbb 100644 --- a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/combined_design_autoscale.md +++ b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/combined_design_autoscale.md @@ -144,6 +144,9 @@ If event-based approach is being used, then additional prerequisites - configura 6. Deploy infrastructure: `terraform apply -auto-approve` 7. Destroy infrastructure if needed: `terraform destroy -auto-approve` +Note: +To deploy the Prisma AIRS product, uncomment the designated (airs_deployment = true) line in the terraform.tfvars file. + ## Additional Reading ### Lambda function @@ -246,7 +249,8 @@ To enable access from the session manager, the Internet connection for a public | Name | Source | Version | |------|--------|---------| -| [app\_lb](#module\_app\_lb) | ../../modules/nlb | n/a | +| [app\_alb](#module\_app\_alb) | ../../modules/alb | n/a | +| [app\_nlb](#module\_app\_nlb) | ../../modules/nlb | n/a | | [gwlb](#module\_gwlb) | ../../modules/gwlb | n/a | | [gwlbe\_endpoint](#module\_gwlbe\_endpoint) | ../../modules/gwlb_endpoint_set | n/a | | [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | @@ -281,22 +285,25 @@ To enable access from the session manager, the Internet connection for a public | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `any` | n/a | yes | -| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `gwlb`: key of GWLB
- `vpc`: key of VPC
- `subnet_group`: key of subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
gwlb = string
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
}))
| `{}` | no | -| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: VPC key
- `subnet_group`: subnet\_group key

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
}))
| `{}` | no | +| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `custom_names`: Optional map of names of the VPC Endpoints, used to override the default naming generated from the input `name`.
Each key is the Availability Zone identifier, for example `us-east-1b`.
- `gwlb`: key of GWLB. Required when GWLB Endpoint must connect to GWLB's service name
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint
- `cloudngfw_key`(optional): Key of the Cloud NGFW. Required when GWLB Endpoint must connect to Cloud NGFW's service name

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
custom\_names = optional(map(string), {})
gwlb = optional(string)
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
delay = optional(number, 0)
tags = optional(map(string))
cloudngfw\_key = optional(string)
}))
| `{}` | no | +| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
tg\_name = optional(string)
target\_instances = optional(map(object({
id = string
})), {})
acceptance\_required = optional(bool, false)
allowed\_principals = optional(list(string), [])
deregistration\_delay = optional(number)
health\_check\_enabled = optional(bool)
health\_check\_interval = optional(number, 5)
health\_check\_matcher = optional(string)
health\_check\_path = optional(string)
health\_check\_port = optional(number, 80)
health\_check\_protocol = optional(string)
health\_check\_timeout = optional(number)
healthy\_threshold = optional(number, 3)
unhealthy\_threshold = optional(number, 3)
stickiness\_type = optional(string)
rebalance\_flows = optional(string, "no\_rebalance")
lb\_tags = optional(map(string), {})
lb\_target\_group\_tags = optional(map(string), {})
endpoint\_service\_tags = optional(map(string), {})
enable\_lb\_deletion\_protection = optional(bool)
}))
| `{}` | no | | [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | n/a | yes | -| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `name`: name of NAT Gateway
- `vpc`: VPC key
- `subnet_group`: subnet\_group key

Example:
natgws = {
security\_nat\_gw = {
name = "natgw"
vpc = "security\_vpc"
subnet\_group = "natgw"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
}))
| `{}` | no | -| [panorama\_attachment](#input\_panorama\_attachment) | A object defining TGW attachment and CIDR for Panorama.

Following properties are available:
- `transit_gateway_attachment_id`: ID of attachment for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
transit\_gateway\_attachment\_id = "tgw-attach-123456789"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
transit\_gateway\_attachment\_id = string
vpc\_cidr = string
})
| `null` | no | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | +| [panorama\_attachment](#input\_panorama\_attachment) | A object defining TGW attachment and CIDR for Panorama.

Following properties are available:
- `tgw_key`: key of the TGW for Panorama attachment
- `transit_gateway_attachment_id`: ID of attachment for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
tgw\_key = "tgw"
transit\_gateway\_attachment\_id = "tgw-attach-123456789"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
tgw\_key = string
transit\_gateway\_attachment\_id = string
vpc\_cidr = string
})
|
{
"tgw\_key": "tgw",
"transit\_gateway\_attachment\_id": null,
"vpc\_cidr": "10.255.0.0/24"
}
| no | | [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | -| [spoke\_lbs](#input\_spoke\_lbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
vpc = string
subnet\_group = string
vms = list(string)
}))
| `{}` | no | -| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `vpc`: key 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 VM
- `type`: EC2 type VM

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t2.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = string
}))
| `{}` | no | -| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | -| [tgw](#input\_tgw) | A object defining Transit Gateway.

Following properties are available:
- `create`: set to false, if existing TGW needs to be reused
- `id`: id of existing TGW or null
- `name`: name of TGW to create or use
- `asn`: ASN number
- `route_tables`: map of route tables
- `attachments`: map of TGW attachments

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route\_tables = {
"from\_security\_vpc" = {
create = true
name = "from\_security"
}
}
attachments = {
security = {
name = "vmseries"
vpc = "security\_vpc"
subnet\_group = "tgw\_attach"
route\_table = "from\_security\_vpc"
propagate\_routes\_to = ["from\_spoke\_vpc"]
}
}
}
|
object({
create = bool
id = string
name = string
asn = string
route\_tables = map(object({
create = bool
name = string
}))
attachments = map(object({
name = string
vpc = string
subnet\_group = string
route\_table = string
propagate\_routes\_to = list(string)
}))
})
| n/a | yes | -| [vmseries\_asgs](#input\_vmseries\_asgs) | A map defining Autoscaling Groups with VM-Series instances.

Following properties are available:
- `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
- `gwlb`: key of GWLB
- `zones`: zones for the Autoscaling Group to be built in
- `interfaces`: configuration of network interfaces for VM-Series used by Lamdba while provisioning new VM-Series in autoscaling group
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `asg`: the number of Amazon EC2 instances that should be running in the group (desired, minimum, maximum)
- `scaling_plan`: scaling plan with attributes
- `enabled`: `true` if automatic dynamic scaling policy should be created
- `metric_name`: name of the metric used in dynamic scaling policy
- `estimated_instance_warmup`: estimated time, in seconds, until a newly launched instance can contribute to the CloudWatch metrics
- `target_value`: target value for the metric used in dynamic scaling policy
- `statistic`: statistic of the metric. Valid values: Average, Maximum, Minimum, SampleCount, Sum
- `cloudwatch_namespace`: name of CloudWatch namespace, where metrics are available (it should be the same as namespace configured in VM-Series plugin in PAN-OS)
- `tags`: tags configured for dynamic scaling policy
- `launch_template_version`: launch template version to use to launch instances
- `instance_refresh`: instance refresh for ASG defined by several attributes (please README for module `asg` for more details)

Example:
vmseries\_asgs = {
main\_asg = {
bootstrap\_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable" # TODO: update here
panorama-server = "" # TODO: update here
auth-key = "" # TODO: update here
dgname = "" # TODO: update here
tplname = "" # TODO: update here
dhcp-send-hostname = "yes" # TODO: update here
dhcp-send-client-id = "yes" # TODO: update here
dhcp-accept-server-hostname = "yes" # TODO: update here
dhcp-accept-server-domain = "yes" # TODO: update here
}

panos\_version = "10.2.3" # TODO: update here
ebs\_kms\_id = "alias/aws/ebs" # TODO: update here

vpc = "security\_vpc"
gwlb = "security\_gwlb"

interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
subnet\_group = "public"
create\_public\_ip = false
source\_dest\_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired\_cap = 0
min\_size = 0
max\_size = 4
lambda\_execute\_pip\_install\_once = true
}

scaling\_plan = {
enabled = true
metric\_name = "panSessionActive"
estimated\_instance\_warmup = 900
target\_value = 75
statistic = "Average"
cloudwatch\_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch\_template\_version = "1"

instance\_refresh = {
strategy = "Rolling"
preferences = {
checkpoint\_delay = 3600
checkpoint\_percentages = [50, 100]
instance\_warmup = 1200
min\_healthy\_percentage = 50
skip\_matching = false
auto\_rollback = false
scale\_in\_protected\_instances = "Ignore"
standby\_instances = "Ignore"
}
triggers = []
}

delicense = {
enabled = true
ssm\_param\_name = "example\_param\_store\_delicense" # TODO: update here
}
}
}
|
map(object({
bootstrap\_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = string
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos\_version = string
ebs\_kms\_id = string

vpc = string
gwlb = string

zones = map(any)

interfaces = map(object({
device\_index = number
security\_group = string
subnet\_group = string
create\_public\_ip = bool
source\_dest\_check = bool
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

asg = object({
desired\_cap = number
min\_size = number
max\_size = number
lambda\_execute\_pip\_install\_once = bool
})

scaling\_plan = object({
enabled = bool
metric\_name = string
estimated\_instance\_warmup = number
target\_value = number
statistic = string
cloudwatch\_namespace = string
tags = map(string)
})

launch\_template\_version = string

instance\_refresh = object({
strategy = string
preferences = object({
checkpoint\_delay = number
checkpoint\_percentages = list(number)
instance\_warmup = number
min\_healthy\_percentage = number
skip\_matching = bool
auto\_rollback = bool
scale\_in\_protected\_instances = string
standby\_instances = string
})
triggers = list(string)
})

delicense = object({
enabled = bool
ssm\_param\_name = string
})
}))
| `{}` | no | -| [vpcs](#input\_vpcs) | A 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
- `subnet_group`: identity of the same purpose subnets group such as management
- `nacl`: key of NACL (can be null)
- `routes`: map of routes with properties:
- `vpc` - VPC key
- `subnet_group` - subnet\_group key
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "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 = 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 | +| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = map(object({
protocol = optional(string, "HTTP")
port = optional(number, 80)
health\_check\_port = optional(string, "80")
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
health\_check\_interval = optional(number, 10)
listener\_rules = map(object({
target\_protocol = string
target\_port = number
path\_pattern = list(string)
}))
}))
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| `{}` | no | +| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `name`: Name of the NLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs
- `internal_lb`(optional): flag to switch between internet\_facing and internal NLB
- `balance_rules` (optional): Rules defining the method of traffic balancing

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
vms = list(string)
internal\_lb = optional(bool, false)
balance\_rules = map(object({
protocol = string
port = string
stickiness = optional(bool, true)
}))
}))
| `{}` | no | +| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 VM type

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t3.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = optional(string, "t3.micro")
}))
| `{}` | no | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | `""` | no | +| [tgw\_attachments](#input\_tgw\_attachments) | A object defining Transit Gateway Attachments.

Following properties are available:
- `tgw_key`: key of the TGW to be attached
- `create`: set to false, if existing TGW attachment needs to be reused
- `id`: id of existing TGW
- `security_vpc_attachment`: set to true if default route from spoke VPCs towards
this attachment should be created
- `name`: name of the TGW attachment to create or use
- `asn`: ASN number
- `vpc`: key of the attaching VPC
- `route_table`: route table key created under TGW taht must be associated with attachment
- `propagate_routes_to`: route table key created under TGW

Example:
tgw\_attachments = {
security = {
tgw\_key = "tgw"
name = "vmseries"
vpc = "security\_vpc"
subnet\_group = "tgw\_attach"
route\_table = "from\_security\_vpc"
propagate\_routes\_to = "from\_spoke\_vpc"
}
}
|
map(object({
tgw\_key = string
create = optional(bool, true)
id = optional(string)
security\_vpc\_attachment = optional(bool, false)
name = string
vpc = string
subnet\_group = string
route\_table = string
propagate\_routes\_to = string
appliance\_mode\_support = optional(string, "enable")
dns\_support = optional(string, null)
tags = optional(map(string))
}))
| `{}` | no | +| [tgws](#input\_tgws) | A object defining Transit Gateway.

Following properties are available:
- `create`: set to false, if existing TGW needs to be reused
- `id`: id of existing TGW
- `name`: name of TGW to create or use
- `asn`: ASN number
- `route_tables`: map of route tables

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route\_tables = {
"from\_security\_vpc" = {
create = true
name = "from\_security"
}
}
}
|
map(object({
create = optional(bool, true)
id = optional(string)
name = string
asn = string
route\_tables = map(object({
create = bool
name = string
}))
}))
| `{}` | no | +| [vmseries\_asgs](#input\_vmseries\_asgs) | A map defining Autoscaling Groups with VM-Series instances.

Following properties are available:
- `bootstrap_options`: VM-Seriess bootstrap options used to connect to Panorama
- `airs_deployment (optional|false)`: flag to deploy AIRS product type
- `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
- `gwlb`: key of GWLB
- `zones`: zones for the Autoscaling Group to be built in
- `interfaces`: configuration of network interfaces for VM-Series used by Lamdba while provisioning new VM-Series in autoscaling group
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `asg`: the number of Amazon EC2 instances that should be running in the group (desired, minimum, maximum)
- `scaling_plan`: scaling plan with attributes
- `enabled`: `true` if automatic dynamic scaling policy should be created
- `metric_name`: name of the metric used in dynamic scaling policy
- `estimated_instance_warmup`: estimated time, in seconds, until a newly launched instance can contribute to the CloudWatch metrics
- `target_value`: target value for the metric used in dynamic scaling policy
- `statistic`: statistic of the metric. Valid values: Average, Maximum, Minimum, SampleCount, Sum
- `cloudwatch_namespace`: name of CloudWatch namespace, where metrics are available (it should be the same as namespace configured in VM-Series plugin in PAN-OS)
- `tags`: tags configured for dynamic scaling policy
- `launch_template_version`: launch template version to use to launch instances
- `instance_refresh`: instance refresh for ASG defined by several attributes (please see README for module `asg` for more details)

Example:
vmseries\_asgs = {
main\_asg = {
bootstrap\_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable" # TODO: update here
panorama-server = "" # TODO: update here
auth-key = "" # TODO: update here
dgname = "" # TODO: update here
tplname = "" # TODO: update here
dhcp-send-hostname = "yes" # TODO: update here
dhcp-send-client-id = "yes" # TODO: update here
dhcp-accept-server-hostname = "yes" # TODO: update here
dhcp-accept-server-domain = "yes" # TODO: update here
}

panos\_version = "10.2.3" # TODO: update here
ebs\_kms\_id = "alias/aws/ebs" # TODO: update here

vpc = "security\_vpc"
gwlb = "security\_gwlb"

zones = {
"01" = "us-west-1a"
"02" = "us-west-1b"
}

interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
subnet\_group = "public"
create\_public\_ip = false
source\_dest\_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired\_cap = 0
min\_size = 0
max\_size = 4
lambda\_execute\_pip\_install\_once = true
}

scaling\_plan = {
enabled = true
metric\_name = "panSessionActive"
estimated\_instance\_warmup = 900
target\_value = 75
statistic = "Average"
cloudwatch\_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch\_template\_version = "1"

instance\_refresh = {
strategy = "Rolling"
preferences = {
checkpoint\_delay = 3600
checkpoint\_percentages = [50, 100]
instance\_warmup = 1200
min\_healthy\_percentage = 50
skip\_matching = false
auto\_rollback = false
scale\_in\_protected\_instances = "Ignore"
standby\_instances = "Ignore"
}
triggers = []
}
}
}
|
map(object({
bootstrap\_options = object({
hostname = optional(string)
mgmt-interface-swap = string
plugin-op-commands = string
op-command-modes = optional(string)
panorama-server = string
panorama-server-2 = optional(string)
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
cgname = optional(string)
dns-primary = optional(string)
dns-secondary = optional(string)
dhcp-send-hostname = optional(string)
dhcp-send-client-id = optional(string)
dhcp-accept-server-hostname = optional(string)
dhcp-accept-server-domain = optional(string)
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

airs\_deployment = optional(bool, false)
panos\_version = string
ebs\_kms\_id = string
vmseries\_ami\_id = optional(string)
vmseries\_product\_code = optional(string, "6njl1pau431dv1qxipg63mvah")
include\_deprecated\_ami = optional(bool, false)
instance\_type = optional(string, "m5.xlarge")
ebs\_encrypted = optional(bool, true)
enable\_instance\_termination\_protection = optional(bool, false)
enable\_monitoring = optional(bool, false)
fw\_license\_type = optional(string, "byol")


vpc = string
gwlb = optional(string)

zones = map(any)

interfaces = map(object({
device\_index = number
security\_group = string
subnet\_group = string
create\_public\_ip = optional(bool, false)
source\_dest\_check = bool
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

lambda\_timeout = optional(number, 30)
delicense\_ssm\_param\_name = optional(string)
delicense\_enabled = optional(bool, false)
reserved\_concurrent\_executions = optional(number, 100)
asg\_name = optional(string, "asg")
asg = object({
desired\_cap = optional(number, 2)
min\_size = optional(number, 1)
max\_size = optional(number, 2)
lambda\_execute\_pip\_install\_once = optional(bool, false)
lifecycle\_hook\_timeout = optional(number, 300)
health\_check = optional(object({
grace\_period = number
type = string
}), {
grace\_period = 300
type = "EC2"
})
delete\_timeout = optional(string, "20m")
suspended\_processes = optional(list(string), [])
})

scaling\_plan = object({
enabled = optional(bool, false)
metric\_name = optional(string, "")
estimated\_instance\_warmup = optional(number, 900)
target\_value = optional(number, 70)
statistic = optional(string, "Average")
cloudwatch\_namespace = optional(string, "VMseries\_dimensions")
tags = map(string)
})

launch\_template\_update\_default\_version = optional(bool, true)
launch\_template\_version = optional(string, "$Latest")
tag\_specifications\_targets = optional(list(string), ["instance", "volume", "network-interface"])

instance\_refresh = optional(object({
strategy = string
preferences = object({
checkpoint\_delay = number
checkpoint\_percentages = list(number)
instance\_warmup = number
min\_healthy\_percentage = number
skip\_matching = bool
auto\_rollback = bool
scale\_in\_protected\_instances = string
standby\_instances = string
})
triggers = list(string)
}), null)

application\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
security\_group = optional(string)
rules = optional(any)
}), {})

network\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
rules = optional(any)
}), {})
}))
| `{}` | no | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | ### Outputs | Name | Description | |------|-------------| -| [app\_inspected\_dns\_name](#output\_app\_inspected\_dns\_name) | FQDN of App Internal Load Balancer.
Can be used in VM-Series configuration to balance traffic between the application instances. | +| [application\_load\_balancers](#output\_application\_load\_balancers) | FQDNs of Application Load Balancers | +| [network\_load\_balancers](#output\_network\_load\_balancers) | FQDNs of Network Load Balancers. | \ No newline at end of file diff --git a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/isolated_design.md b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/isolated_design.md index 74e128b16..802583c27 100644 --- a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/isolated_design.md +++ b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/isolated_design.md @@ -95,10 +95,11 @@ To enable access from the session manager, the Internet connection for a public | Name | Source | Version | |------|--------|---------| +| [app\_alb](#module\_app\_alb) | ../../modules/alb | n/a | +| [app\_nlb](#module\_app\_nlb) | ../../modules/nlb | n/a | | [gwlb](#module\_gwlb) | ../../modules/gwlb | n/a | | [gwlbe\_endpoint](#module\_gwlbe\_endpoint) | ../../modules/gwlb_endpoint_set | n/a | -| [public\_alb](#module\_public\_alb) | ../../modules/alb | n/a | -| [public\_nlb](#module\_public\_nlb) | ../../modules/nlb | n/a | +| [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | | [subnet\_sets](#module\_subnet\_sets) | ../../modules/subnet_set | n/a | | [vmseries](#module\_vmseries) | ../../modules/vmseries | n/a | | [vpc](#module\_vpc) | ../../modules/vpc | n/a | @@ -128,17 +129,18 @@ To enable access from the session manager, the Internet connection for a public | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `any` | n/a | yes | -| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `gwlb`: key of GWLB
- `vpc`: key of VPC
- `subnet_group`: key of subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
gwlb = string
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
}))
| `{}` | no | -| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
}))
| `{}` | no | +| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `custom_names`: Optional map of names of the VPC Endpoints, used to override the default naming generated from the input `name`.
Each key is the Availability Zone identifier, for example `us-east-1b`.
- `gwlb`: key of GWLB. Required when GWLB Endpoint must connect to GWLB's service name
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint
- `cloudngfw_key`(optional): Key of the Cloud NGFW. Required when GWLB Endpoint must connect to Cloud NGFW's service name

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
custom\_names = optional(map(string), {})
gwlb = optional(string)
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
delay = optional(number, 0)
tags = optional(map(string))
cloudngfw\_key = optional(string)
}))
| `{}` | no | +| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
tg\_name = optional(string)
target\_instances = optional(map(object({
id = string
})), {})
acceptance\_required = optional(bool, false)
allowed\_principals = optional(list(string), [])
deregistration\_delay = optional(number)
health\_check\_enabled = optional(bool)
health\_check\_interval = optional(number, 5)
health\_check\_matcher = optional(string)
health\_check\_path = optional(string)
health\_check\_port = optional(number, 80)
health\_check\_protocol = optional(string)
health\_check\_timeout = optional(number)
healthy\_threshold = optional(number, 3)
unhealthy\_threshold = optional(number, 3)
stickiness\_type = optional(string)
rebalance\_flows = optional(string, "no\_rebalance")
lb\_tags = optional(map(string), {})
lb\_target\_group\_tags = optional(map(string), {})
endpoint\_service\_tags = optional(map(string), {})
enable\_lb\_deletion\_protection = optional(bool)
}))
| `{}` | no | | [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | n/a | yes | -| [panorama\_connection](#input\_panorama\_connection) | A object defining VPC peering and CIDR for Panorama.

Following properties are available:
- `security_vpc`: key of the security VPC
- `peering_vpc_id`: ID of the VPC for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
security\_vpc = "security\_vpc"
peering\_vpc\_id = "vpc-1234567890"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
security\_vpc = string
peering\_vpc\_id = string
vpc\_cidr = string
})
| `null` | no | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | +| [panorama\_connection](#input\_panorama\_connection) | A object defining VPC peering and CIDR for Panorama.

Following properties are available:
- `security_vpc`: key of the security VPC
- `peering_vpc_id`: ID of the VPC for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
security\_vpc = "security\_vpc"
peering\_vpc\_id = "vpc-1234567890"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
security\_vpc = string
peering\_vpc\_id = string
vpc\_cidr = string
})
|
{
"peering\_vpc\_id": null,
"security\_vpc": "security\_vpc",
"vpc\_cidr": "10.255.0.0/24"
}
| no | | [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | -| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnet\_groups in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = any
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| n/a | yes | -| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
vpc = string
subnet\_group = string
vms = list(string)
}))
| `{}` | no | -| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 type VM

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t2.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = string
}))
| `{}` | no | -| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | -| [vmseries](#input\_vmseries) | A 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
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces
Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
"02" = { az = "eu-central-1b" }
}
# 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"
# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security\_gwlb"
interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
vpc = "security\_vpc"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
vpc = "security\_vpc"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
vpc = "security\_vpc"
subnet\_group = "public"
create\_public\_ip = true
source\_dest\_check = false
}
}
# Value of `gwlb\_endpoint` must match key of objects stored in `gwlb\_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}
system\_services = {
dns\_primary = "4.2.2.2" # TODO: update here
dns\_secondy = null # TODO: update here
ntp\_primary = "pool.ntp.org" # TODO: update here
ntp\_secondy = null # TODO: update here
}
application\_lb = null
network\_lb = null
}
}
|
map(object({
instances = map(object({
az = string
}))

bootstrap\_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = string
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos\_version = string
ebs\_kms\_id = string

vpc = string
gwlb = string

interfaces = map(object({
device\_index = number
security\_group = string
vpc = string
subnet\_group = string
create\_public\_ip = bool
source\_dest\_check = bool
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

system\_services = object({
dns\_primary = string
dns\_secondy = string
ntp\_primary = string
ntp\_secondy = string
})

application\_lb = object({
name = string
rules = any
})

network\_lb = object({
name = string
rules = any
})
}))
| `{}` | no | -| [vpcs](#input\_vpcs) | A 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
- `subnet_group`: identity of the same purpose subnets group such as management
- `nacl`: key of NACL (can be null)
- `routes`: map of routes with properties:
- `vpc` - key of VPC
- `subnet_group` - key of subnet\_group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "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
subnet\_group = string
nacl = string
}))
routes = map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
}))
}))
| `{}` | no | +| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = map(object({
protocol = optional(string, "HTTP")
port = optional(number, 80)
health\_check\_port = optional(string, "80")
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
health\_check\_interval = optional(number, 10)
listener\_rules = map(object({
target\_protocol = string
target\_port = number
path\_pattern = list(string)
}))
}))
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| `{}` | no | +| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `name`: Name of the NLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs
- `internal_lb`(optional): flag to switch between internet\_facing and internal NLB
- `balance_rules` (optional): Rules defining the method of traffic balancing

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
vms = list(string)
internal\_lb = optional(bool, false)
balance\_rules = map(object({
protocol = string
port = string
stickiness = optional(bool, true)
}))
}))
| `{}` | no | +| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 VM type

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t3.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = optional(string, "t3.micro")
}))
| `{}` | no | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | `""` | no | +| [vmseries](#input\_vmseries) | A 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
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces

Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
"02" = { az = "eu-central-1b" }
}

# 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"

# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security\_gwlb"

interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
vpc = "security\_vpc"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
vpc = "security\_vpc"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
vpc = "security\_vpc"
subnet\_group = "public"
create\_public\_ip = true
source\_dest\_check = false
}
}

# Value of `gwlb\_endpoint` must match key of objects stored in `gwlb\_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

system\_services = {
dns\_primary = "4.2.2.2" # TODO: update here
dns\_secondy = null # TODO: update here
ntp\_primary = "pool.ntp.org" # TODO: update here
ntp\_secondy = null # TODO: update here
}
}
}
|
map(object({
instances = map(object({
az = string
name = optional(string)
}))

bootstrap\_options = object({
hostname = optional(string)
mgmt-interface-swap = string
plugin-op-commands = string
op-command-modes = optional(string)
panorama-server = string
panorama-server-2 = optional(string)
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
cgname = optional(string)
dns-primary = optional(string)
dns-secondary = optional(string)
dhcp-send-hostname = optional(string)
dhcp-send-client-id = optional(string)
dhcp-accept-server-hostname = optional(string)
dhcp-accept-server-domain = optional(string)
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos\_version = string
vmseries\_ami\_id = optional(string)
vmseries\_product\_code = optional(string, "6njl1pau431dv1qxipg63mvah")
include\_deprecated\_ami = optional(bool, false)
instance\_type = optional(string, "m5.xlarge")
ebs\_encrypted = optional(bool, true)
ebs\_kms\_id = optional(string, "alias/aws/ebs")
enable\_instance\_termination\_protection = optional(bool, false)
enable\_monitoring = optional(bool, false)
fw\_license\_type = optional(string, "byol")

vpc = string
gwlb = optional(string)

interfaces = map(object({
device\_index = number
name = optional(string)
description = optional(string)
security\_group = string
subnet\_group = string
create\_public\_ip = optional(bool, false)
eip\_allocation\_id = optional(string)
source\_dest\_check = optional(bool, false)
private\_ips = optional(list(string))
ipv6\_address\_count = optional(number, null)
public\_ipv4\_pool = optional(string)
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

tags = optional(map(string))

system\_services = object({
dns\_primary = string
dns\_secondy = optional(string)
ntp\_primary = string
ntp\_secondy = optional(string)
})

application\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
security\_group = optional(string)
rules = optional(any)
}), {})

network\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
rules = optional(any)
}), {})
}))
| `{}` | no | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | ### Outputs diff --git a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/isolated_design_autoscale.md b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/isolated_design_autoscale.md index faf53bfab..61001bc80 100644 --- a/products/terraform/docs/swfw/aws/vmseries/reference-architectures/isolated_design_autoscale.md +++ b/products/terraform/docs/swfw/aws/vmseries/reference-architectures/isolated_design_autoscale.md @@ -204,10 +204,11 @@ statistic = "Maximum" | Name | Source | Version | |------|--------|---------| +| [app\_alb](#module\_app\_alb) | ../../modules/alb | n/a | +| [app\_nlb](#module\_app\_nlb) | ../../modules/nlb | n/a | | [gwlb](#module\_gwlb) | ../../modules/gwlb | n/a | | [gwlbe\_endpoint](#module\_gwlbe\_endpoint) | ../../modules/gwlb_endpoint_set | n/a | -| [public\_alb](#module\_public\_alb) | ../../modules/alb | n/a | -| [public\_nlb](#module\_public\_nlb) | ../../modules/nlb | n/a | +| [natgw\_set](#module\_natgw\_set) | ../../modules/nat_gateway_set | n/a | | [subnet\_sets](#module\_subnet\_sets) | ../../modules/subnet_set | n/a | | [vm\_series\_asg](#module\_vm\_series\_asg) | ../../modules/asg | n/a | | [vpc](#module\_vpc) | ../../modules/vpc | n/a | @@ -236,17 +237,18 @@ statistic = "Maximum" | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [global\_tags](#input\_global\_tags) | Global tags configured for all provisioned resources | `any` | n/a | yes | -| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `gwlb`: key of GWLB
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
gwlb = string
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
}))
| `{}` | no | -| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
}))
| `{}` | no | +| [gwlb\_endpoints](#input\_gwlb\_endpoints) | A map defining GWLB endpoints.

Following properties are available:
- `name`: name of the GWLB endpoint
- `custom_names`: Optional map of names of the VPC Endpoints, used to override the default naming generated from the input `name`.
Each key is the Availability Zone identifier, for example `us-east-1b`.
- `gwlb`: key of GWLB. Required when GWLB Endpoint must connect to GWLB's service name
- `vpc`: key of VPC
- `subnet_group`: key of the subnet\_group
- `act_as_next_hop`: set to `true` if endpoint is part of an IGW route table e.g. for inbound traffic
- `from_igw_to_vpc`: VPC to which traffic from IGW is routed to the GWLB endpoint
- `from_igw_to_subnet_group` : subnet\_group to which traffic from IGW is routed to the GWLB endpoint
- `cloudngfw_key`(optional): Key of the Cloud NGFW. Required when GWLB Endpoint must connect to Cloud NGFW's service name

Example:
gwlb\_endpoints = {
security\_gwlb\_eastwest = {
name = "eastwest-gwlb-endpoint"
gwlb = "security\_gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlbe\_eastwest"
act\_as\_next\_hop = false
}
}
|
map(object({
name = string
custom\_names = optional(map(string), {})
gwlb = optional(string)
vpc = string
subnet\_group = string
act\_as\_next\_hop = bool
from\_igw\_to\_vpc = optional(string)
from\_igw\_to\_subnet\_group = optional(string)
delay = optional(number, 0)
tags = optional(map(string))
cloudngfw\_key = optional(string)
}))
| `{}` | no | +| [gwlbs](#input\_gwlbs) | A map defining Gateway Load Balancers.

Following properties are available:
- `name`: name of the GWLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group

Example:
gwlbs = {
security\_gwlb = {
name = "security-gwlb"
vpc = "security\_vpc"
subnet\_group = "gwlb"
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
tg\_name = optional(string)
target\_instances = optional(map(object({
id = string
})), {})
acceptance\_required = optional(bool, false)
allowed\_principals = optional(list(string), [])
deregistration\_delay = optional(number)
health\_check\_enabled = optional(bool)
health\_check\_interval = optional(number, 5)
health\_check\_matcher = optional(string)
health\_check\_path = optional(string)
health\_check\_port = optional(number, 80)
health\_check\_protocol = optional(string)
health\_check\_timeout = optional(number)
healthy\_threshold = optional(number, 3)
unhealthy\_threshold = optional(number, 3)
stickiness\_type = optional(string)
rebalance\_flows = optional(string, "no\_rebalance")
lb\_tags = optional(map(string), {})
lb\_target\_group\_tags = optional(map(string), {})
endpoint\_service\_tags = optional(map(string), {})
enable\_lb\_deletion\_protection = optional(bool)
}))
| `{}` | no | | [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | n/a | yes | -| [panorama\_connection](#input\_panorama\_connection) | A object defining VPC peering and CIDR for Panorama.

Following properties are available:
- `security_vpc`: key of the security VPC
- `peering_vpc_id`: ID of the VPC for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
security\_vpc = "security\_vpc"
peering\_vpc\_id = "vpc-1234567890"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
security\_vpc = string
peering\_vpc\_id = string
vpc\_cidr = string
})
| `null` | no | +| [natgws](#input\_natgws) | A map defining NAT Gateways.

Following properties are available:
- `nat_gateway_names`: A map, where each key is an Availability Zone name, for example "eu-west-1b".
Each value in the map is a custom name of a NAT Gateway in that Availability Zone.
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `nat_gateway_tags`: A map containing NAT GW tags
- `create_eip`: Defaults to true, uses a data source to find EIP when set to false
- `eips`: Optional map of Elastic IP attributes. Each key must be an Availability Zone name.

Example:
natgws = {
sec\_natgw = {
vpc = "security\_vpc"
subnet\_group = "natgw"
nat\_gateway\_names = {
"eu-west-1a" = "nat-gw-1"
"eu-west-1b" = "nat-gw-2"
}
eips ={
"eu-west-1a" = {
name = "natgw-1-pip"
}
}
}
}
|
map(object({
create\_nat\_gateway = optional(bool, true)
nat\_gateway\_names = optional(map(string), {})
vpc = string
subnet\_group = string
nat\_gateway\_tags = optional(map(string), {})
create\_eip = optional(bool, true)
eips = optional(map(object({
name = optional(string)
public\_ip = optional(string)
id = optional(string)
eip\_tags = optional(map(string), {})
})), {})
}))
| `{}` | no | +| [panorama\_connection](#input\_panorama\_connection) | A object defining VPC peering and CIDR for Panorama.

Following properties are available:
- `security_vpc`: key of the security VPC
- `peering_vpc_id`: ID of the VPC for Panorama
- `vpc_cidr`: CIDR of the VPC, where Panorama is deployed

Example:
panorama = {
security\_vpc = "security\_vpc"
peering\_vpc\_id = "vpc-1234567890"
vpc\_cidr = "10.255.0.0/24"
}
|
object({
security\_vpc = string
peering\_vpc\_id = string
vpc\_cidr = string
})
|
{
"peering\_vpc\_id": null,
"security\_vpc": "security\_vpc",
"vpc\_cidr": "10.255.0.0/24"
}
| no | | [region](#input\_region) | AWS region used to deploy whole infrastructure | `string` | n/a | yes | -| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnet\_groups in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = any
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| n/a | yes | -| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
vpc = string
subnet\_group = string
vms = list(string)
}))
| `{}` | no | -| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 type VM

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t2.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = string
}))
| `{}` | no | -| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | -| [vmseries\_asgs](#input\_vmseries\_asgs) | A map defining Autoscaling Groups with VM-Series instances.

Following properties are available:
- `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
- `gwlb`: key of GWLB
- `zones`: zones for the Autoscaling Group to be built in
- `interfaces`: configuration of network interfaces for VM-Series used by Lamdba while provisioning new VM-Series in autoscaling group
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `asg`: the number of Amazon EC2 instances that should be running in the group (desired, minimum, maximum)
- `scaling_plan`: scaling plan with attributes
- `enabled`: `true` if automatic dynamic scaling policy should be created
- `metric_name`: name of the metric used in dynamic scaling policy
- `estimated_instance_warmup`: estimated time, in seconds, until a newly launched instance can contribute to the CloudWatch metrics
- `target_value`: target value for the metric used in dynamic scaling policy
- `statistic`: statistic of the metric. Valid values: Average, Maximum, Minimum, SampleCount, Sum
- `cloudwatch_namespace`: name of CloudWatch namespace, where metrics are available (it should be the same as namespace configured in VM-Series plugin in PAN-OS)
- `tags`: tags configured for dynamic scaling policy
- `launch_template_version`: launch template version to use to launch instances
- `instance_refresh`: instance refresh for ASG defined by several attributes (please README for module `asg` for more details)

Example:
vmseries\_asgs = {
main\_asg = {
bootstrap\_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable" # TODO: update here
panorama-server = "" # TODO: update here
auth-key = "" # TODO: update here
dgname = "" # TODO: update here
tplname = "" # TODO: update here
dhcp-send-hostname = "yes" # TODO: update here
dhcp-send-client-id = "yes" # TODO: update here
dhcp-accept-server-hostname = "yes" # TODO: update here
dhcp-accept-server-domain = "yes" # TODO: update here
}

panos\_version = "10.2.3" # TODO: update here
ebs\_kms\_id = "alias/aws/ebs" # TODO: update here

vpc = "security\_vpc"
gwlb = "security\_gwlb"

zones = {
"01" = "us-west-1a"
"02" = "us-west-1b"
}

interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
subnet\_group = "public"
create\_public\_ip = false
source\_dest\_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired\_cap = 0
min\_size = 0
max\_size = 4
lambda\_execute\_pip\_install\_once = true
}

scaling\_plan = {
enabled = true
metric\_name = "panSessionActive"
estimated\_instance\_warmup = 900
target\_value = 75
statistic = "Average"
cloudwatch\_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch\_template\_version = "1"

instance\_refresh = {
strategy = "Rolling"
preferences = {
checkpoint\_delay = 3600
checkpoint\_percentages = [50, 100]
instance\_warmup = 1200
min\_healthy\_percentage = 50
skip\_matching = false
auto\_rollback = false
scale\_in\_protected\_instances = "Ignore"
standby\_instances = "Ignore"
}
triggers = []
}
}
}
|
map(object({
bootstrap\_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = string
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos\_version = string
ebs\_kms\_id = string

vpc = string
gwlb = string

zones = map(any)

interfaces = map(object({
device\_index = number
security\_group = string
subnet\_group = string
create\_public\_ip = bool
source\_dest\_check = bool
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

asg = object({
desired\_cap = number
min\_size = number
max\_size = number
lambda\_execute\_pip\_install\_once = bool
})

scaling\_plan = object({
enabled = bool
metric\_name = string
estimated\_instance\_warmup = number
target\_value = number
statistic = string
cloudwatch\_namespace = string
tags = map(string)
})

launch\_template\_version = string

instance\_refresh = object({
strategy = string
preferences = object({
checkpoint\_delay = number
checkpoint\_percentages = list(number)
instance\_warmup = number
min\_healthy\_percentage = number
skip\_matching = bool
auto\_rollback = bool
scale\_in\_protected\_instances = string
standby\_instances = string
})
triggers = list(string)
})
}))
| `{}` | no | -| [vpcs](#input\_vpcs) | A 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
- `subnet_group`: identity of the same purpose subnets group such as management
- `nacl`: key of NACL (can be null)
- `routes`: map of routes with properties:
- `vpc`: key of VPC
- `subnet_group`: key of subnet\_group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "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
subnet\_group = string
nacl = string
}))
routes = map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
}))
}))
| `{}` | no | +| [spoke\_albs](#input\_spoke\_albs) | A map defining Application Load Balancers deployed in spoke VPCs.

Following properties are available:
- `rules`: Rules defining the method of traffic balancing
- `vms`: Instances to be the target group for ALB
- `vpc`: The VPC in which the load balancer is to be run
- `subnet_group`: The subnets in which the Load Balancer is to be run
- `security_gropus`: Security Groups to be associated with the ALB
 | 
map(object({
rules = map(object({
protocol = optional(string, "HTTP")
port = optional(number, 80)
health\_check\_port = optional(string, "80")
health\_check\_matcher = optional(string, "200")
health\_check\_path = optional(string, "/")
health\_check\_interval = optional(number, 10)
listener\_rules = map(object({
target\_protocol = string
target\_port = number
path\_pattern = list(string)
}))
}))
vms = list(string)
vpc = string
subnet\_group = string
security\_groups = string
}))
| `{}` | no | +| [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

Following properties are available:
- `name`: Name of the NLB
- `vpc`: key of the VPC
- `subnet_group`: key of the subnet\_group
- `vms`: keys of spoke VMs
- `internal_lb`(optional): flag to switch between internet\_facing and internal NLB
- `balance_rules` (optional): Rules defining the method of traffic balancing

Example:
spoke\_lbs = {
"app1-nlb" = {
vpc = "app1\_vpc"
subnet\_group = "app1\_lb"
vms = ["app1\_vm01", "app1\_vm02"]
}
}
|
map(object({
name = string
vpc = string
subnet\_group = string
vms = list(string)
internal\_lb = optional(bool, false)
balance\_rules = map(object({
protocol = string
port = string
stickiness = optional(bool, true)
}))
}))
| `{}` | no | +| [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

Following properties are available:
- `az`: name of the Availability Zone
- `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 VM
- `type`: EC2 VM type

Example:
spoke\_vms = {
"app1\_vm01" = {
az = "eu-central-1a"
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
security\_group = "app1\_vm"
type = "t3.micro"
}
}
|
map(object({
az = string
vpc = string
subnet\_group = string
security\_group = string
type = optional(string, "t3.micro")
}))
| `{}` | no | +| [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | `""` | no | +| [vmseries\_asgs](#input\_vmseries\_asgs) | A map defining Autoscaling Groups with VM-Series instances.

Following properties are available:
- `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
- `gwlb`: key of GWLB
- `zones`: zones for the Autoscaling Group to be built in
- `interfaces`: configuration of network interfaces for VM-Series used by Lamdba while provisioning new VM-Series in autoscaling group
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `asg`: the number of Amazon EC2 instances that should be running in the group (desired, minimum, maximum)
- `scaling_plan`: scaling plan with attributes
- `enabled`: `true` if automatic dynamic scaling policy should be created
- `metric_name`: name of the metric used in dynamic scaling policy
- `estimated_instance_warmup`: estimated time, in seconds, until a newly launched instance can contribute to the CloudWatch metrics
- `target_value`: target value for the metric used in dynamic scaling policy
- `statistic`: statistic of the metric. Valid values: Average, Maximum, Minimum, SampleCount, Sum
- `cloudwatch_namespace`: name of CloudWatch namespace, where metrics are available (it should be the same as namespace configured in VM-Series plugin in PAN-OS)
- `tags`: tags configured for dynamic scaling policy
- `launch_template_version`: launch template version to use to launch instances
- `instance_refresh`: instance refresh for ASG defined by several attributes (please see README for module `asg` for more details)

Example:
vmseries\_asgs = {
main\_asg = {
bootstrap\_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable" # TODO: update here
panorama-server = "" # TODO: update here
auth-key = "" # TODO: update here
dgname = "" # TODO: update here
tplname = "" # TODO: update here
dhcp-send-hostname = "yes" # TODO: update here
dhcp-send-client-id = "yes" # TODO: update here
dhcp-accept-server-hostname = "yes" # TODO: update here
dhcp-accept-server-domain = "yes" # TODO: update here
}

panos\_version = "10.2.3" # TODO: update here
ebs\_kms\_id = "alias/aws/ebs" # TODO: update here

vpc = "security\_vpc"
gwlb = "security\_gwlb"

zones = {
"01" = "us-west-1a"
"02" = "us-west-1b"
}

interfaces = {
private = {
device\_index = 0
security\_group = "vmseries\_private"
subnet\_group = "private"
create\_public\_ip = false
source\_dest\_check = false
}
mgmt = {
device\_index = 1
security\_group = "vmseries\_mgmt"
subnet\_group = "mgmt"
create\_public\_ip = true
source\_dest\_check = true
}
public = {
device\_index = 2
security\_group = "vmseries\_public"
subnet\_group = "public"
create\_public\_ip = false
source\_dest\_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb\_endpoint = "app1\_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb\_endpoint = "app2\_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only\_1\_outbound = {
gwlb\_endpoint = "security\_gwlb\_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only\_1\_eastwest = {
gwlb\_endpoint = "security\_gwlb\_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired\_cap = 0
min\_size = 0
max\_size = 4
lambda\_execute\_pip\_install\_once = true
}

scaling\_plan = {
enabled = true
metric\_name = "panSessionActive"
estimated\_instance\_warmup = 900
target\_value = 75
statistic = "Average"
cloudwatch\_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch\_template\_version = "1"

instance\_refresh = {
strategy = "Rolling"
preferences = {
checkpoint\_delay = 3600
checkpoint\_percentages = [50, 100]
instance\_warmup = 1200
min\_healthy\_percentage = 50
skip\_matching = false
auto\_rollback = false
scale\_in\_protected\_instances = "Ignore"
standby\_instances = "Ignore"
}
triggers = []
}
}
}
|
map(object({
bootstrap\_options = object({
hostname = optional(string)
mgmt-interface-swap = string
plugin-op-commands = string
op-command-modes = optional(string)
panorama-server = string
panorama-server-2 = optional(string)
auth-key = optional(string)
vm-auth-key = optional(string)
dgname = string
tplname = optional(string)
cgname = optional(string)
dns-primary = optional(string)
dns-secondary = optional(string)
dhcp-send-hostname = optional(string)
dhcp-send-client-id = optional(string)
dhcp-accept-server-hostname = optional(string)
dhcp-accept-server-domain = optional(string)
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos\_version = string
vmseries\_ami\_id = optional(string)
vmseries\_product\_code = optional(string, "6njl1pau431dv1qxipg63mvah")
include\_deprecated\_ami = optional(bool, false)
instance\_type = optional(string, "m5.xlarge")
ebs\_encrypted = optional(bool, true)
ebs\_kms\_id = optional(string, "alias/aws/ebs")
enable\_instance\_termination\_protection = optional(bool, false)
enable\_monitoring = optional(bool, false)
fw\_license\_type = optional(string, "byol")


vpc = string
gwlb = optional(string)

zones = map(any)

interfaces = map(object({
device\_index = number
security\_group = string
subnet\_group = string
create\_public\_ip = optional(bool, false)
source\_dest\_check = bool
}))

subinterfaces = map(map(object({
gwlb\_endpoint = string
subinterface = string
})))

lambda\_timeout = optional(number, 30)
delicense\_ssm\_param\_name = optional(string)
delicense\_enabled = optional(bool, false)
reserved\_concurrent\_executions = optional(number, 100)
asg\_name = optional(string, "asg")
asg = object({
desired\_cap = optional(number, 2)
min\_size = optional(number, 1)
max\_size = optional(number, 2)
lambda\_execute\_pip\_install\_once = optional(bool, false)
lifecycle\_hook\_timeout = optional(number, 300)
health\_check = optional(object({
grace\_period = number
type = string
}), {
grace\_period = 300
type = "EC2"
})
delete\_timeout = optional(string, "20m")
suspended\_processes = optional(list(string), [])
})

scaling\_plan = object({
enabled = optional(bool, false)
metric\_name = optional(string, "")
estimated\_instance\_warmup = optional(number, 900)
target\_value = optional(number, 70)
statistic = optional(string, "Average")
cloudwatch\_namespace = optional(string, "VMseries\_dimensions")
tags = map(string)
})

launch\_template\_update\_default\_version = optional(bool, true)
launch\_template\_version = optional(string, "$Latest")
tag\_specifications\_targets = optional(list(string), ["instance", "volume", "network-interface"])

instance\_refresh = optional(object({
strategy = string
preferences = object({
checkpoint\_delay = number
checkpoint\_percentages = list(number)
instance\_warmup = number
min\_healthy\_percentage = number
skip\_matching = bool
auto\_rollback = bool
scale\_in\_protected\_instances = string
standby\_instances = string
})
triggers = list(string)
}), null)

application\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
security\_group = optional(string)
rules = optional(any)
}), {})

network\_lb = optional(object({
name = optional(string)
subnet\_group = optional(string)
rules = optional(any)
}), {})
}))
| `{}` | no | +| [vpcs](#input\_vpcs) | A 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 the VPC
- `subnet_group`: key of the subnet group
- `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", subnet\_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet\_group = "vm", nacl = null }
}
routes = {
vm\_default = {
vpc = "app1\_vpc"
subnet\_group = "app1\_vm"
to\_cidr = "0.0.0.0/0"
next\_hop\_key = "app1"
next\_hop\_type = "transit\_gateway\_attachment"
}
}
}
}
|
map(object({
name = string
create\_vpc = optional(bool, true)
cidr = string
secondary\_cidr\_blocks = optional(list(string), [])
assign\_generated\_ipv6\_cidr\_block = optional(bool)
use\_internet\_gateway = optional(bool, false)
name\_internet\_gateway = optional(string)
create\_internet\_gateway = optional(bool, true)
route\_table\_internet\_gateway = optional(string)
create\_vpn\_gateway = optional(bool, false)
vpn\_gateway\_amazon\_side\_asn = optional(string)
name\_vpn\_gateway = optional(string)
route\_table\_vpn\_gateway = optional(string)
enable\_dns\_hostnames = optional(bool, true)
enable\_dns\_support = optional(bool, true)
instance\_tenancy = optional(string, "default")
nacls = optional(map(object({
name = string
rules = map(object({
rule\_number = number
egress = bool
protocol = string
rule\_action = string
cidr\_block = string
from\_port = optional(number)
to\_port = optional(number)
}))
})), {})
security\_groups = optional(map(object({
name = string
rules = map(object({
description = optional(string)
type = string
cidr\_blocks = optional(list(string))
ipv6\_cidr\_blocks = optional(list(string))
from\_port = string
to\_port = string
protocol = string
prefix\_list\_ids = optional(list(string))
source\_security\_groups = optional(list(string))
self = optional(bool)
}))
})), {})
subnets = optional(map(object({
name = optional(string, "")
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)
route\_table\_name = optional(string)
associate\_route\_table = optional(bool, true)
local\_tags = optional(map(string), {})
map\_public\_ip\_on\_launch = optional(bool, false)
})), {})
routes = optional(map(object({
vpc = string
subnet\_group = string
to\_cidr = string
next\_hop\_key = string
next\_hop\_type = string
destination\_type = optional(string, "ipv4")
managed\_prefix\_list\_id = optional(string)
})), {})
create\_dhcp\_options = optional(bool, false)
domain\_name = optional(string)
domain\_name\_servers = optional(list(string))
ntp\_servers = optional(list(string))
vpc\_tags = optional(map(string), {})
}))
| `{}` | no | ### Outputs diff --git a/products/terraform/docs/swfw/azure/cloudngfw/modules/name_templater.md b/products/terraform/docs/swfw/azure/cloudngfw/modules/name_templater.md index 03829ea7a..c035885eb 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/modules/name_templater.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/modules/name_templater.md @@ -61,7 +61,7 @@ As you can see: * the `prefix` key is just a placeholder that eventually is replaced with the value of `name_prefix` * the `__random__` string is replaced with a name of a [random pet](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) (in case you need to randomize some name, for testing purposes for example) * the `__default__` string is replaced with a resource abbreviation. - This abbreviations are defined with `var.abbreviations` variable. The module contains basic abbreviations following Microsoft suggestions, but they can be overridden with custom definitions. + This abbreviations are defined with `var.abbreviations` variable. The module contains basic abbreviations following Microsoft suggestions, but they can be overriden with custom definitions. The important part is that the `resource_type` has to match an entry in `abbreviations` variable, otherwise the abbreviation will be replaced with an empty string. To create the actual resource name the following code can be used: @@ -199,4 +199,4 @@ Type: map(string) Default value: `map[application_gw:agw application_insights:appi availability_set:avail bastion:bas data_disk:disk file_share:share load_balancer:lb log_analytics_workspace:log managed_identity:id nat_gw:ng network_interface:nic nsg:nsg nsg_rule:nsgsr os_disk:osdisk public_ip:pip public_ip_prefix:ippre resource_group:rg route_table:rt service_endpoint:se storage_account:st subnet:snet udr:udr virtual_machine:vm virtual_machine_scale_set:vmss virtual_network_gateway:vgw vnet:vnet vnet_peering:peer]` -[back to list](#modules-optional-inputs) +[back to list](#modules-optional-inputs) \ No newline at end of file diff --git a/products/terraform/docs/swfw/azure/cloudngfw/modules/vmseries.md b/products/terraform/docs/swfw/azure/cloudngfw/modules/vmseries.md index ddcd4ff32..dc9d3f1a1 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/modules/vmseries.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/modules/vmseries.md @@ -212,7 +212,7 @@ Firewall parameters configuration. This map contains basic, as well as some optional Firewall parameters. Both types contain sane defaults. Nevertheless they should be at least reviewed to meet deployment requirements. -List of either required or important properties: +List of either required or important properties: - `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series Deployment Guide* as only a few selected sizes are supported. @@ -231,7 +231,7 @@ List of either required or important properties: For more details on bootstrapping [see documentation](https://docs.paloaltonetworks.com/vm-series/10-2/vm-series-deployment/bootstrap-the-vm-series-firewall/create-the-init-cfgtxt-file/init-cfgtxt-file-components). -List of other, optional properties: +List of other, optional properties: - `avset_id` - (`string`, optional, default to `null`) identifier of the Availability Set to use. - `capacity_reservation_group_id` - (`string`, optional, defaults to `null`) specifies the ID of the Capacity Reservation Group @@ -250,7 +250,7 @@ List of other, optional properties: - `identity_type` - (`string`, optional, defaults to `SystemAssigned`) type of Managed Service Identity that should be configured on this VM. Can be one of "SystemAssigned", "UserAssigned" or "SystemAssigned, UserAssigned". -- `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be +- `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be assigned to this VM. Required only if `identity_type` is not "SystemAssigned". @@ -290,26 +290,30 @@ Interfaces will be attached to VM in the order you define here, therefore: - The first should be the management interface, which does not participate in data filtering. - The remaining ones are the dataplane interfaces. - + Following configuration options are available: - `name` - (`string`, required) the interface name. - `subnet_id` - (`string`, required) ID of an existing subnet to create the interface in. -- `ip_configuration_name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. -- `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. When - skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is guarantied not - to change as long as the VM is running. Any stop/deallocate/restart operation might cause - the IP to change. -- `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the interface. -- `public_ip_name` - (`string`, optional, defaults to `null`) name of the public IP to associate with the - interface. When `create_public_ip` is set to `true` this will become a name of a newly - created Public IP interface. Otherwise this is a name of an existing interfaces that will - be sourced and attached to the interface. Not used when using `public_ip` module. -- `public_ip_resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of a Resource Group that - contains public IP that that will be associated with the interface. Used only when - `create_public_ip` is `false`. -- `public_ip_id` - (`string`, optional, defaults to `null`) ID of the public IP to associate with the - interface. Property is used when public IP is not created or sourced within this module. +- ip_configurations - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary + one. + - `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. + When skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is + guaranteed not to change as long as the VM is running. Any stop/deallocate/restart + operation might cause the IP to change. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the interface. + **Note!** When you define multiple IP configurations, exactly one must be the primary. + - `public_ip_name` - (`string`, optional, defaults to `null`) name of the public IP to associate with the + interface. When `create_public_ip` is set to `true` this will become a name of a newly + created Public IP interface. Otherwise this is a name of an existing interfaces that will + be sourced and attached to the interface. Not used when using `public_ip` module. + - `public_ip_resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of a Resource Group that + contains public IP that that will be associated with the interface. Used only when + `create_public_ip` is `false`. + - `public_ip_id` - (`string`, optional, defaults to `null`) ID of the public IP to associate with the + interface. Property is used when public IP is not created or sourced within this module. - `attach_to_lb_backend_pool` - (`bool`, optional, defaults to `false`) set to `true` if you would like to associate this interface with a Load Balancer backend pool. - `lb_backend_pool_id` - (`string`, optional, defaults to `null`) ID of an existing backend pool to associate the @@ -327,8 +331,13 @@ Example: { name = "fw-mgmt" subnet_id = azurerm_subnet.my_mgmt_subnet.id - public_ip_name = "fw-mgmt-pip" - create_public_ip = true + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + public_ip_name = "fw-mgmt-pip" + } }, # public interface reusing an existing public IP resource { @@ -336,8 +345,35 @@ Example: subnet_id = azurerm_subnet.my_pub_subnet.id attach_to_lb_backend_pool = true lb_backend_pool_id = module.inbound_lb.backend_pool_id - create_public_ip = false - public_ip_name = "fw-public-pip" + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + public_ip_name = "fw-public-pip" + } + }, + # interface with 2 IP addresses + { + name = "fw-two-ips" + subnet_id = azurerm_subnet.my_pub_subnet.id + attach_to_lb_backend_pool = true + lb_backend_pool_id = module.inbound_lb.backend_pool_id + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + private_ip_address = "10.0.0.5" + public_ip_name = "fw-public-pip" + }, + secondary-ip = { + name = "secondary-ip" + primary = false + create_public_ip = false + private_ip_address = "10.0.0.6" + public_ip_name = "fw-public-pip" + } }, ] ``` @@ -347,18 +383,21 @@ Type: ```hcl list(object({ - name = string - subnet_id = string - ip_configuration_name = optional(string, "primary") - create_public_ip = optional(bool, false) - public_ip_name = optional(string) - public_ip_resource_group_name = optional(string) - public_ip_id = optional(string) - private_ip_address = optional(string) - lb_backend_pool_id = optional(string) - attach_to_lb_backend_pool = optional(bool, false) - appgw_backend_pool_id = optional(string) - attach_to_appgw_backend_pool = optional(bool, false) + name = string + subnet_id = string + ip_configurations = map(object({ + name = optional(string, "primary") + primary = optional(bool, true) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_id = optional(string) + private_ip_address = optional(string) + })) + lb_backend_pool_id = optional(string) + attach_to_lb_backend_pool = optional(bool, false) + appgw_backend_pool_id = optional(string) + attach_to_appgw_backend_pool = optional(bool, false) })) ``` diff --git a/products/terraform/docs/swfw/azure/cloudngfw/modules/vmss.md b/products/terraform/docs/swfw/azure/cloudngfw/modules/vmss.md index 57ee7e8d3..5598afc27 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/modules/vmss.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/modules/vmss.md @@ -54,6 +54,19 @@ probe would target the management interface which could lead to false-positives. probes, while the data plane remains unconfigured. An easy solution would to bo configure an interface swap, unfortunately this is not available in the Azure VM-Series image yet. +## Orchestration modes + +This module allows you to deploy a Virtual Machine Scale Set (VMSS) with a configurable orchestration mode. The choice of mode is +determined by the `orchestration_type` variable, which provides a single point of control over the VMSS deployment. + +Uniform Orchestration: if `orchestration_type` is set to `Uniform`, traditional uniform orchestration mode is used, where all +VMs are managed as a single entity. + +Flexible Orchestration: if `orchestration_type` is set to `Flexible`, new flexible orchestration mode is used. For this mode to +function correctly, the VMSS's identity type must be set to `UserAssigned` in order to manage individual VMs in the set. + +By default, the Uniform Orchestration is used by the module. + ## Custom Metrics and Autoscaling Firewalls can publish custom metrics (for example `panSessionUtilization`) to Azure Application Insights to improve the @@ -144,6 +157,8 @@ Name | Version | Source | Description - `linux_virtual_machine_scale_set` (managed) - `monitor_autoscale_setting` (managed) +- `orchestrated_virtual_machine_scale_set` (managed) +- `user_assigned_identity` (managed) - `public_ip_prefix` (data) ### Required Inputs @@ -292,22 +307,26 @@ Following configuration options are available: - `name` - (`string`, required) the interface name. - `subnet_id` - (`string`, required) ID of an existing subnet to create the interface in. -- `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the interface. -- `pip_domain_name_label` - (`string`, optional, defaults to `null`) the Prefix which should be used for the Domain - Name Label for each Virtual Machine Instance. -- `pip_idle_timeout_in_minutes` - (`number`, optional, defaults to Azure default) the Idle Timeout in minutes for the Public - IP Address, possible values are in the range from 4 to 32. -- `pip_prefix_name` - (`string`, optional) the name of an existing Public IP Address Prefix from where Public IP - Addresses should be allocated. -- `pip_prefix_resource_group_name` - (`string`, optional, defaults to the VMSS's RG) name of a Resource Group hosting an - existing Public IP Prefix resource. -- `pip_prefix_id` - (`string`, optional) you can specify Public IP Prefix ID as an alternative to the - properties above (name and resource group), in case you want to avoid using a data source - block. +- `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary + one. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the interface. + - `pip_domain_name_label` - (`string`, optional, defaults to `null`) the Prefix which should be used for the Domain + Name Label for each Virtual Machine Instance. + - `pip_idle_timeout_in_minutes` - (`number`, optional, defaults to Azure default) the Idle Timeout in minutes for the + Public IP Address, possible values are in the range from 4 to 32. + - `pip_prefix_name` - (`string`, optional) the name of an existing Public IP Address Prefix from where Public + IP Addresses should be allocated. + - `pip_prefix_resource_group_name` - (`string`, optional, defaults to the VMSS's RG) name of a Resource Group hosting an + existing Public IP Prefix resource. + - `pip_prefix_id` - (`string`, optional) you can specify Public IP Prefix ID as an alternative to the + properties above (name and resource group), in case you want to avoid using a data + source block. - `lb_backend_pool_ids` - (`list`, optional, defaults to `[]`) a list of identifiers of existing Load Balancer - backend pools to associate the interface with. + backend pools to associate the interface with. Only applied to primary IP configuration. - `appgw_backend_pool_ids` - (`list`, optional, defaults to `[]`) a list of identifier of Application Gateway's backend - pools to associate the interface with. + pools to associate the interface with. Only applied to primary IP configuration. Example: @@ -316,16 +335,33 @@ Example: { name = "management" subnet_id = azurerm_subnet.my_mgmt_subnet.id - create_pip = true + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + } }, { name = "private" subnet_id = azurerm_subnet.my_priv_subnet.id + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + } }, { name = "public" subnet_id = azurerm_subnet.my_pub_subnet.id lb_backend_pool_ids = [azurerm_lb_backend_address_pool.lb_backend.id] + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + } } ] ``` @@ -335,16 +371,20 @@ Type: ```hcl list(object({ - name = string - subnet_id = string - create_public_ip = optional(bool, false) - pip_domain_name_label = optional(string) - pip_idle_timeout_in_minutes = optional(number) - pip_prefix_name = optional(string) - pip_prefix_resource_group_name = optional(string) - pip_prefix_id = optional(string) - lb_backend_pool_ids = optional(list(string), []) - appgw_backend_pool_ids = optional(list(string), []) + name = string + subnet_id = string + ip_configurations = map(object({ + name = optional(string, "primary") + primary = optional(bool, true) + create_public_ip = optional(bool, false) + pip_domain_name_label = optional(string) + pip_idle_timeout_in_minutes = optional(number) + pip_prefix_name = optional(string) + pip_prefix_resource_group_name = optional(string) + pip_prefix_id = optional(string) + })) + lb_backend_pool_ids = optional(list(string), []) + appgw_backend_pool_ids = optional(list(string), []) })) ``` @@ -372,14 +412,16 @@ Nevertheless they should be at least reviewed to meet deployment requirements. List of either required or important properties: -- `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series - Deployment Guide* as only few selected sizes are supported. The default one is a VM-300 equivalent. -- `zones` - (`list`, optional, defaults to `null`) a list of Availability Zones in which VMs from this Scale Set - will be created. -- `disk_type` - (`string`, optional, defaults to `StandardSSD_LRS`) type of Managed Disk which should be created, - possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` - values). -- `bootstrap_options` - (`string`, optional) bootstrap options to pass to VM-Series instance. +- `orchestration_type` - (`string`, optional, defaults to `Uniform`) this variable is used to select between the Uniform or + Flexible Scale Set orchestration modes. Possible values are `Uniform` and `Flexible`. +- `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only few selected sizes are supported. The default one is a VM-300 equivalent. +- `zones` - (`list`, optional, defaults to `null`) a list of Availability Zones in which VMs from this Scale Set + will be created. Zone balance is available from at least 2 zones. +- `disk_type` - (`string`, optional, defaults to `StandardSSD_LRS`) type of Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` + values). +- `bootstrap_options` - (`string`, optional) bootstrap options to pass to VM-Series instance. Proper syntax is a string of semicolon separated properties, for example: @@ -399,9 +441,11 @@ List of other, optional properties: used to encrypt this VM's disk. - `encryption_at_host_enabled` - (`bool`, optional, defaults to Azure defaults) should all of disks be encrypted by enabling Encryption at Host. -- `overprovision` - (`bool`, optional, defaults to `true`) See the [provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine_scale_set). -- `platform_fault_domain_count` - (`number`, optional, defaults to Azure defaults) specifies the number of fault domains that - are used by this Virtual Machine Scale Set. +- `overprovision` - (`bool`, optional, defaults to `true`) controls whether Azure should over-provision Virtual + Machines in the Scale Set for improved deployment time and provisioning success rate. +- `platform_fault_domain_count` - (`number`, optional, defaults to `5`) specifies the number of fault domains that are used + by this Virtual Machine Scale Set. The Flexible orchestration mode requires this parameter + to be set. - `single_placement_group` - (`bool`, optional, defaults to Azure defaults) when `true` this Virtual Machine Scale Set will be limited to a Single Placement Group, which means the number of instances will be capped at 100 Virtual Machines. @@ -412,7 +456,8 @@ List of other, optional properties: files, when skipped a managed Storage Account will be used (preferred). - `identity_type` - (`string`, optional, defaults to `SystemAssigned`) type of Managed Service Identity that should be configured on this VM. Can be one of "SystemAssigned", "UserAssigned" or - "SystemAssigned, UserAssigned". + "SystemAssigned, UserAssigned". For the Flexible orchestration mode this parameter must be + configured to "UserAssigned". - `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be assigned to this VM. Required only if `identity_type` is not "SystemAssigned". @@ -421,6 +466,7 @@ Type: ```hcl object({ + orchestration_type = optional(string, "Uniform") size = optional(string, "Standard_D3_v2") bootstrap_options = optional(string) zones = optional(list(string)) @@ -429,7 +475,7 @@ object({ allow_extension_operations = optional(bool, false) encryption_at_host_enabled = optional(bool) overprovision = optional(bool, true) - platform_fault_domain_count = optional(number) + platform_fault_domain_count = optional(number, 5) single_placement_group = optional(bool) capacity_reservation_group_id = optional(string) disk_encryption_set_id = optional(string) diff --git a/products/terraform/docs/swfw/azure/cloudngfw/modules/vwan.md b/products/terraform/docs/swfw/azure/cloudngfw/modules/vwan.md index f709b5e3c..3c9a36248 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/modules/vwan.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/modules/vwan.md @@ -377,6 +377,8 @@ Each object represents one Connection and supports the following properties: - `name` - (`string`, required) the name of the Connection, must be unique within the Virtual Hub. - `connection_type` - (`string`, required) the type of Connection, use `Vnet` for Virtual Network connections. - `remote_virtual_network_id` - (`string`, optional) the resource ID of a remote Virtual Network. +- `internet_security_enabled` - (`bool`, optional) the parameter that enables internet-bound traffic from the connected VNet + to be routed through the Virtual Hub for inspection by a Network Virtual Appliance (NVA). - `hub_key` - (`string`, required) the key referencing the Virtual Hub. - `vpn_site_key` - (`string`, optional) the key referencing the VPN Site used in this Connection. - `vpn_link` - (`list`, optional, defaults to `[]`) list of VPN link configurations, each object supports the @@ -428,6 +430,7 @@ map(object({ connection_type = string hub_key = string remote_virtual_network_id = optional(string) + internet_security_enabled = optional(bool) vpn_site_key = optional(string) vpn_link = optional(list(object({ vpn_link_name = string diff --git a/products/terraform/docs/swfw/azure/vmseries/modules/vmseries.md b/products/terraform/docs/swfw/azure/vmseries/modules/vmseries.md index ddcd4ff32..dc9d3f1a1 100644 --- a/products/terraform/docs/swfw/azure/vmseries/modules/vmseries.md +++ b/products/terraform/docs/swfw/azure/vmseries/modules/vmseries.md @@ -212,7 +212,7 @@ Firewall parameters configuration. This map contains basic, as well as some optional Firewall parameters. Both types contain sane defaults. Nevertheless they should be at least reviewed to meet deployment requirements. -List of either required or important properties: +List of either required or important properties: - `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series Deployment Guide* as only a few selected sizes are supported. @@ -231,7 +231,7 @@ List of either required or important properties: For more details on bootstrapping [see documentation](https://docs.paloaltonetworks.com/vm-series/10-2/vm-series-deployment/bootstrap-the-vm-series-firewall/create-the-init-cfgtxt-file/init-cfgtxt-file-components). -List of other, optional properties: +List of other, optional properties: - `avset_id` - (`string`, optional, default to `null`) identifier of the Availability Set to use. - `capacity_reservation_group_id` - (`string`, optional, defaults to `null`) specifies the ID of the Capacity Reservation Group @@ -250,7 +250,7 @@ List of other, optional properties: - `identity_type` - (`string`, optional, defaults to `SystemAssigned`) type of Managed Service Identity that should be configured on this VM. Can be one of "SystemAssigned", "UserAssigned" or "SystemAssigned, UserAssigned". -- `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be +- `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be assigned to this VM. Required only if `identity_type` is not "SystemAssigned". @@ -290,26 +290,30 @@ Interfaces will be attached to VM in the order you define here, therefore: - The first should be the management interface, which does not participate in data filtering. - The remaining ones are the dataplane interfaces. - + Following configuration options are available: - `name` - (`string`, required) the interface name. - `subnet_id` - (`string`, required) ID of an existing subnet to create the interface in. -- `ip_configuration_name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. -- `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. When - skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is guarantied not - to change as long as the VM is running. Any stop/deallocate/restart operation might cause - the IP to change. -- `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the interface. -- `public_ip_name` - (`string`, optional, defaults to `null`) name of the public IP to associate with the - interface. When `create_public_ip` is set to `true` this will become a name of a newly - created Public IP interface. Otherwise this is a name of an existing interfaces that will - be sourced and attached to the interface. Not used when using `public_ip` module. -- `public_ip_resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of a Resource Group that - contains public IP that that will be associated with the interface. Used only when - `create_public_ip` is `false`. -- `public_ip_id` - (`string`, optional, defaults to `null`) ID of the public IP to associate with the - interface. Property is used when public IP is not created or sourced within this module. +- ip_configurations - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary + one. + - `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. + When skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is + guaranteed not to change as long as the VM is running. Any stop/deallocate/restart + operation might cause the IP to change. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the interface. + **Note!** When you define multiple IP configurations, exactly one must be the primary. + - `public_ip_name` - (`string`, optional, defaults to `null`) name of the public IP to associate with the + interface. When `create_public_ip` is set to `true` this will become a name of a newly + created Public IP interface. Otherwise this is a name of an existing interfaces that will + be sourced and attached to the interface. Not used when using `public_ip` module. + - `public_ip_resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of a Resource Group that + contains public IP that that will be associated with the interface. Used only when + `create_public_ip` is `false`. + - `public_ip_id` - (`string`, optional, defaults to `null`) ID of the public IP to associate with the + interface. Property is used when public IP is not created or sourced within this module. - `attach_to_lb_backend_pool` - (`bool`, optional, defaults to `false`) set to `true` if you would like to associate this interface with a Load Balancer backend pool. - `lb_backend_pool_id` - (`string`, optional, defaults to `null`) ID of an existing backend pool to associate the @@ -327,8 +331,13 @@ Example: { name = "fw-mgmt" subnet_id = azurerm_subnet.my_mgmt_subnet.id - public_ip_name = "fw-mgmt-pip" - create_public_ip = true + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + public_ip_name = "fw-mgmt-pip" + } }, # public interface reusing an existing public IP resource { @@ -336,8 +345,35 @@ Example: subnet_id = azurerm_subnet.my_pub_subnet.id attach_to_lb_backend_pool = true lb_backend_pool_id = module.inbound_lb.backend_pool_id - create_public_ip = false - public_ip_name = "fw-public-pip" + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + public_ip_name = "fw-public-pip" + } + }, + # interface with 2 IP addresses + { + name = "fw-two-ips" + subnet_id = azurerm_subnet.my_pub_subnet.id + attach_to_lb_backend_pool = true + lb_backend_pool_id = module.inbound_lb.backend_pool_id + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + private_ip_address = "10.0.0.5" + public_ip_name = "fw-public-pip" + }, + secondary-ip = { + name = "secondary-ip" + primary = false + create_public_ip = false + private_ip_address = "10.0.0.6" + public_ip_name = "fw-public-pip" + } }, ] ``` @@ -347,18 +383,21 @@ Type: ```hcl list(object({ - name = string - subnet_id = string - ip_configuration_name = optional(string, "primary") - create_public_ip = optional(bool, false) - public_ip_name = optional(string) - public_ip_resource_group_name = optional(string) - public_ip_id = optional(string) - private_ip_address = optional(string) - lb_backend_pool_id = optional(string) - attach_to_lb_backend_pool = optional(bool, false) - appgw_backend_pool_id = optional(string) - attach_to_appgw_backend_pool = optional(bool, false) + name = string + subnet_id = string + ip_configurations = map(object({ + name = optional(string, "primary") + primary = optional(bool, true) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_id = optional(string) + private_ip_address = optional(string) + })) + lb_backend_pool_id = optional(string) + attach_to_lb_backend_pool = optional(bool, false) + appgw_backend_pool_id = optional(string) + attach_to_appgw_backend_pool = optional(bool, false) })) ``` diff --git a/products/terraform/docs/swfw/azure/vmseries/modules/vmss.md b/products/terraform/docs/swfw/azure/vmseries/modules/vmss.md index 57ee7e8d3..5598afc27 100644 --- a/products/terraform/docs/swfw/azure/vmseries/modules/vmss.md +++ b/products/terraform/docs/swfw/azure/vmseries/modules/vmss.md @@ -54,6 +54,19 @@ probe would target the management interface which could lead to false-positives. probes, while the data plane remains unconfigured. An easy solution would to bo configure an interface swap, unfortunately this is not available in the Azure VM-Series image yet. +## Orchestration modes + +This module allows you to deploy a Virtual Machine Scale Set (VMSS) with a configurable orchestration mode. The choice of mode is +determined by the `orchestration_type` variable, which provides a single point of control over the VMSS deployment. + +Uniform Orchestration: if `orchestration_type` is set to `Uniform`, traditional uniform orchestration mode is used, where all +VMs are managed as a single entity. + +Flexible Orchestration: if `orchestration_type` is set to `Flexible`, new flexible orchestration mode is used. For this mode to +function correctly, the VMSS's identity type must be set to `UserAssigned` in order to manage individual VMs in the set. + +By default, the Uniform Orchestration is used by the module. + ## Custom Metrics and Autoscaling Firewalls can publish custom metrics (for example `panSessionUtilization`) to Azure Application Insights to improve the @@ -144,6 +157,8 @@ Name | Version | Source | Description - `linux_virtual_machine_scale_set` (managed) - `monitor_autoscale_setting` (managed) +- `orchestrated_virtual_machine_scale_set` (managed) +- `user_assigned_identity` (managed) - `public_ip_prefix` (data) ### Required Inputs @@ -292,22 +307,26 @@ Following configuration options are available: - `name` - (`string`, required) the interface name. - `subnet_id` - (`string`, required) ID of an existing subnet to create the interface in. -- `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the interface. -- `pip_domain_name_label` - (`string`, optional, defaults to `null`) the Prefix which should be used for the Domain - Name Label for each Virtual Machine Instance. -- `pip_idle_timeout_in_minutes` - (`number`, optional, defaults to Azure default) the Idle Timeout in minutes for the Public - IP Address, possible values are in the range from 4 to 32. -- `pip_prefix_name` - (`string`, optional) the name of an existing Public IP Address Prefix from where Public IP - Addresses should be allocated. -- `pip_prefix_resource_group_name` - (`string`, optional, defaults to the VMSS's RG) name of a Resource Group hosting an - existing Public IP Prefix resource. -- `pip_prefix_id` - (`string`, optional) you can specify Public IP Prefix ID as an alternative to the - properties above (name and resource group), in case you want to avoid using a data source - block. +- `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary + one. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the interface. + - `pip_domain_name_label` - (`string`, optional, defaults to `null`) the Prefix which should be used for the Domain + Name Label for each Virtual Machine Instance. + - `pip_idle_timeout_in_minutes` - (`number`, optional, defaults to Azure default) the Idle Timeout in minutes for the + Public IP Address, possible values are in the range from 4 to 32. + - `pip_prefix_name` - (`string`, optional) the name of an existing Public IP Address Prefix from where Public + IP Addresses should be allocated. + - `pip_prefix_resource_group_name` - (`string`, optional, defaults to the VMSS's RG) name of a Resource Group hosting an + existing Public IP Prefix resource. + - `pip_prefix_id` - (`string`, optional) you can specify Public IP Prefix ID as an alternative to the + properties above (name and resource group), in case you want to avoid using a data + source block. - `lb_backend_pool_ids` - (`list`, optional, defaults to `[]`) a list of identifiers of existing Load Balancer - backend pools to associate the interface with. + backend pools to associate the interface with. Only applied to primary IP configuration. - `appgw_backend_pool_ids` - (`list`, optional, defaults to `[]`) a list of identifier of Application Gateway's backend - pools to associate the interface with. + pools to associate the interface with. Only applied to primary IP configuration. Example: @@ -316,16 +335,33 @@ Example: { name = "management" subnet_id = azurerm_subnet.my_mgmt_subnet.id - create_pip = true + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + } }, { name = "private" subnet_id = azurerm_subnet.my_priv_subnet.id + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + } }, { name = "public" subnet_id = azurerm_subnet.my_pub_subnet.id lb_backend_pool_ids = [azurerm_lb_backend_address_pool.lb_backend.id] + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + } } ] ``` @@ -335,16 +371,20 @@ Type: ```hcl list(object({ - name = string - subnet_id = string - create_public_ip = optional(bool, false) - pip_domain_name_label = optional(string) - pip_idle_timeout_in_minutes = optional(number) - pip_prefix_name = optional(string) - pip_prefix_resource_group_name = optional(string) - pip_prefix_id = optional(string) - lb_backend_pool_ids = optional(list(string), []) - appgw_backend_pool_ids = optional(list(string), []) + name = string + subnet_id = string + ip_configurations = map(object({ + name = optional(string, "primary") + primary = optional(bool, true) + create_public_ip = optional(bool, false) + pip_domain_name_label = optional(string) + pip_idle_timeout_in_minutes = optional(number) + pip_prefix_name = optional(string) + pip_prefix_resource_group_name = optional(string) + pip_prefix_id = optional(string) + })) + lb_backend_pool_ids = optional(list(string), []) + appgw_backend_pool_ids = optional(list(string), []) })) ``` @@ -372,14 +412,16 @@ Nevertheless they should be at least reviewed to meet deployment requirements. List of either required or important properties: -- `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series - Deployment Guide* as only few selected sizes are supported. The default one is a VM-300 equivalent. -- `zones` - (`list`, optional, defaults to `null`) a list of Availability Zones in which VMs from this Scale Set - will be created. -- `disk_type` - (`string`, optional, defaults to `StandardSSD_LRS`) type of Managed Disk which should be created, - possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` - values). -- `bootstrap_options` - (`string`, optional) bootstrap options to pass to VM-Series instance. +- `orchestration_type` - (`string`, optional, defaults to `Uniform`) this variable is used to select between the Uniform or + Flexible Scale Set orchestration modes. Possible values are `Uniform` and `Flexible`. +- `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only few selected sizes are supported. The default one is a VM-300 equivalent. +- `zones` - (`list`, optional, defaults to `null`) a list of Availability Zones in which VMs from this Scale Set + will be created. Zone balance is available from at least 2 zones. +- `disk_type` - (`string`, optional, defaults to `StandardSSD_LRS`) type of Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` + values). +- `bootstrap_options` - (`string`, optional) bootstrap options to pass to VM-Series instance. Proper syntax is a string of semicolon separated properties, for example: @@ -399,9 +441,11 @@ List of other, optional properties: used to encrypt this VM's disk. - `encryption_at_host_enabled` - (`bool`, optional, defaults to Azure defaults) should all of disks be encrypted by enabling Encryption at Host. -- `overprovision` - (`bool`, optional, defaults to `true`) See the [provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine_scale_set). -- `platform_fault_domain_count` - (`number`, optional, defaults to Azure defaults) specifies the number of fault domains that - are used by this Virtual Machine Scale Set. +- `overprovision` - (`bool`, optional, defaults to `true`) controls whether Azure should over-provision Virtual + Machines in the Scale Set for improved deployment time and provisioning success rate. +- `platform_fault_domain_count` - (`number`, optional, defaults to `5`) specifies the number of fault domains that are used + by this Virtual Machine Scale Set. The Flexible orchestration mode requires this parameter + to be set. - `single_placement_group` - (`bool`, optional, defaults to Azure defaults) when `true` this Virtual Machine Scale Set will be limited to a Single Placement Group, which means the number of instances will be capped at 100 Virtual Machines. @@ -412,7 +456,8 @@ List of other, optional properties: files, when skipped a managed Storage Account will be used (preferred). - `identity_type` - (`string`, optional, defaults to `SystemAssigned`) type of Managed Service Identity that should be configured on this VM. Can be one of "SystemAssigned", "UserAssigned" or - "SystemAssigned, UserAssigned". + "SystemAssigned, UserAssigned". For the Flexible orchestration mode this parameter must be + configured to "UserAssigned". - `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be assigned to this VM. Required only if `identity_type` is not "SystemAssigned". @@ -421,6 +466,7 @@ Type: ```hcl object({ + orchestration_type = optional(string, "Uniform") size = optional(string, "Standard_D3_v2") bootstrap_options = optional(string) zones = optional(list(string)) @@ -429,7 +475,7 @@ object({ allow_extension_operations = optional(bool, false) encryption_at_host_enabled = optional(bool) overprovision = optional(bool, true) - platform_fault_domain_count = optional(number) + platform_fault_domain_count = optional(number, 5) single_placement_group = optional(bool) capacity_reservation_group_id = optional(string) disk_encryption_set_id = optional(string) diff --git a/products/terraform/docs/swfw/azure/vmseries/modules/vwan.md b/products/terraform/docs/swfw/azure/vmseries/modules/vwan.md index f709b5e3c..3c9a36248 100644 --- a/products/terraform/docs/swfw/azure/vmseries/modules/vwan.md +++ b/products/terraform/docs/swfw/azure/vmseries/modules/vwan.md @@ -377,6 +377,8 @@ Each object represents one Connection and supports the following properties: - `name` - (`string`, required) the name of the Connection, must be unique within the Virtual Hub. - `connection_type` - (`string`, required) the type of Connection, use `Vnet` for Virtual Network connections. - `remote_virtual_network_id` - (`string`, optional) the resource ID of a remote Virtual Network. +- `internet_security_enabled` - (`bool`, optional) the parameter that enables internet-bound traffic from the connected VNet + to be routed through the Virtual Hub for inspection by a Network Virtual Appliance (NVA). - `hub_key` - (`string`, required) the key referencing the Virtual Hub. - `vpn_site_key` - (`string`, optional) the key referencing the VPN Site used in this Connection. - `vpn_link` - (`list`, optional, defaults to `[]`) list of VPN link configurations, each object supports the @@ -428,6 +430,7 @@ map(object({ connection_type = string hub_key = string remote_virtual_network_id = optional(string) + internet_security_enabled = optional(bool) vpn_site_key = optional(string) vpn_link = optional(list(object({ vpn_link_name = string diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/2ef99143-3dcf-4113-814d-aedca8fcccf3.png b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/2ef99143-3dcf-4113-814d-aedca8fcccf3.png new file mode 100644 index 000000000..2edea159e Binary files /dev/null and b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/2ef99143-3dcf-4113-814d-aedca8fcccf3.png differ diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common.md b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common.md index 6f0c7a98d..224ce1e8c 100644 --- a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common.md +++ b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common.md @@ -1026,16 +1026,16 @@ Default value: `map[]` #### vmseries_universal -A map defining common settings for all created VM-Series instances. - +A map defining common settings for all created VM-Series instances. + It duplicates popular properties from `vmseries` variable, specifically `vmseries.image` and `vmseries.virtual_machine` maps. However, if values are set in those maps, they still take precedence over the ones set within this variable. As a result, all universal properties can be overriden on a per-VM basis. Following properties are supported: -- `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used - instead of the one passed to the module and version for `airs-flex` offer must be provided. +- `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used + instead of the one passed to the module and version for `airs-flex` offer must be provided. - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series Deployment Guide* as only a few selected sizes are supported. @@ -1122,7 +1122,7 @@ The most basic properties are as follows: For all properties and their default values see [module's documentation](../../modules/vmseries#authentication). - `image` - (`map`, optional) properties defining a base image used by the deployed VM. The `image` property is - required (if no common properties were set within `vmseries_universal` variable) but there are only 2 + required (if no common properties were set within `vmseries_universal` variable) but there are only 2 properties (mutually exclusive) that have to be set, either: - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. @@ -1199,7 +1199,15 @@ The most basic properties are as follows: - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. - - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. + - `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary one. + **Note!** When you define multiple IP configurations, exactly one must be the primary. + - `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. When + skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is guarantied not + to change as long as the VM is running. Any stop/deallocate/restart operation might cause + the IP to change. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the interface. - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` variable, network interface that has this property defined will be added to the Load Balancer's backend pool. @@ -1288,17 +1296,20 @@ map(object({ identity_ids = optional(list(string)) }) interfaces = list(object({ - name = string - subnet_key = string - ip_configuration_name = optional(string) - create_public_ip = optional(bool, false) - public_ip_name = optional(string) - public_ip_resource_group_name = optional(string) - public_ip_key = optional(string) - private_ip_address = optional(string) - load_balancer_key = optional(string) - application_gateway_key = optional(string) - appgw_backend_pool_id = optional(string) + name = string + subnet_key = string + ip_configurations = map(object({ + name = optional(string) + primary = optional(bool, true) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + private_ip_address = optional(string) + })) + load_balancer_key = optional(string) + application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) ``` @@ -1335,12 +1346,12 @@ Following properties are supported: [VNET module documentation](../../modules/vnet#route_tables). - `subnets` - (`map`, optional) map of Subnets to create or source, for details see [VNET module documentation](../../modules/vnet#subnets). - - `local_peer_config` - (`map`, optional) a map that contains local peer configuration parameters. This value allows to - set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and - `use_remote_gateways` parameters on the local VNet peering. + - `local_peer_config` - (`map`, optional) a map that contains local peer configuration parameters. This value allows to + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the local VNet peering. - `remote_peer_config` - (`map`, optional) a map that contains remote peer configuration parameters. This value allows to - set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and - `use_remote_gateways` parameters on the remote VNet peering. + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the remote VNet peering. For all properties and their default values see [module's documentation](../../modules/test_infrastructure#vnets). diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common_autoscale.md b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common_autoscale.md index ce164a1b4..910a09cf7 100644 --- a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common_autoscale.md +++ b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common_autoscale.md @@ -1209,7 +1209,10 @@ The basic Scale Set configuration properties are as follows: - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in `var.vnets`. - - `create_public_ip` - (`bool`, optional, defaults to module default) create Public IP for an interface. + - `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary one. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the interface. - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in the `var.loadbalancers` variable, network interface that has this property defined will be added to the Load Balancer's backend pool. @@ -1246,9 +1249,10 @@ map(object({ custom_id = optional(string) })) virtual_machine_scale_set = optional(object({ - size = optional(string) - zones = optional(list(string)) - disk_type = optional(string) + orchestration_type = optional(string) + size = optional(string) + zones = optional(list(string)) + disk_type = optional(string) bootstrap_options = optional(object({ type = optional(string) ip-address = optional(string) @@ -1308,16 +1312,20 @@ map(object({ webhooks_uris = optional(map(string), {}) }), {}) interfaces = list(object({ - name = string - subnet_key = string - create_public_ip = optional(bool) - pip_domain_name_label = optional(string) - pip_idle_timeout_in_minutes = optional(number) - pip_prefix_name = optional(string) - pip_prefix_resource_group_name = optional(string) - pip_prefix_id = optional(string) - load_balancer_key = optional(string) - application_gateway_key = optional(string) + name = string + subnet_key = string + ip_configurations = optional(map(object({ + name = optional(string) + primary = optional(bool, true) + create_public_ip = optional(bool, false) + pip_domain_name_label = optional(string) + pip_idle_timeout_in_minutes = optional(number) + pip_prefix_name = optional(string) + pip_prefix_resource_group_name = optional(string) + pip_prefix_id = optional(string) + }))) + load_balancer_key = optional(string) + application_gateway_key = optional(string) })) autoscaling_profiles = optional(list(object({ name = string diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated.md b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated.md index fb7bdafde..e05f4ef4c 100644 --- a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated.md +++ b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated.md @@ -1030,16 +1030,16 @@ Default value: `map[]` #### vmseries_universal -A map defining common settings for all created VM-Series instances. - +A map defining common settings for all created VM-Series instances. + It duplicates popular properties from `vmseries` variable, specifically `vmseries.image` and `vmseries.virtual_machine` maps. However, if values are set in those maps, they still take precedence over the ones set within this variable. As a result, all universal properties can be overriden on a per-VM basis. Following properties are supported: -- `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used - instead of the one passed to the module and version for `airs-flex` offer must be provided. +- `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used + instead of the one passed to the module and version for `airs-flex` offer must be provided. - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series Deployment Guide* as only a few selected sizes are supported. @@ -1126,7 +1126,7 @@ The most basic properties are as follows: For all properties and their default values see [module's documentation](../../modules/vmseries#authentication). - `image` - (`map`, optional) properties defining a base image used by the deployed VM. The `image` property is - required (if no common properties were set within `vmseries_universal` variable) but there are only 2 + required (if no common properties were set within `vmseries_universal` variable) but there are only 2 properties (mutually exclusive) that have to be set, either: - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. @@ -1203,7 +1203,15 @@ The most basic properties are as follows: - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. - - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. + - `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary one. + **Note!** When you define multiple IP configurations, exactly one must be the primary. + - `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. When + skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is guarantied not + to change as long as the VM is running. Any stop/deallocate/restart operation might cause + the IP to change. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the interface. - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` variable, network interface that has this property defined will be added to the Load Balancer's backend pool. @@ -1292,17 +1300,20 @@ map(object({ identity_ids = optional(list(string)) }) interfaces = list(object({ - name = string - subnet_key = string - ip_configuration_name = optional(string) - create_public_ip = optional(bool, false) - public_ip_name = optional(string) - public_ip_resource_group_name = optional(string) - public_ip_key = optional(string) - private_ip_address = optional(string) - load_balancer_key = optional(string) - application_gateway_key = optional(string) - appgw_backend_pool_id = optional(string) + name = string + subnet_key = string + ip_configurations = map(object({ + name = optional(string) + primary = optional(bool, true) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + private_ip_address = optional(string) + })) + load_balancer_key = optional(string) + application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) ``` @@ -1339,12 +1350,12 @@ Following properties are supported: [VNET module documentation](../../modules/vnet#route_tables). - `subnets` - (`map`, optional) map of Subnets to create or source, for details see [VNET module documentation](../../modules/vnet#subnets). - - `local_peer_config` - (`map`, optional) a map that contains local peer configuration parameters. This value allows to - set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and - `use_remote_gateways` parameters on the local VNet peering. + - `local_peer_config` - (`map`, optional) a map that contains local peer configuration parameters. This value allows to + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the local VNet peering. - `remote_peer_config` - (`map`, optional) a map that contains remote peer configuration parameters. This value allows to - set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and - `use_remote_gateways` parameters on the remote VNet peering. + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the remote VNet peering. For all properties and their default values see [module's documentation](../../modules/test_infrastructure#vnets). diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_autoscale.md b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_autoscale.md index 4f4df4031..7cffa26a0 100644 --- a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_autoscale.md +++ b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_autoscale.md @@ -1026,7 +1026,7 @@ set within this variable. As a result, all universal properties can be overriden Following properties are supported: - `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used - instead of the one passed to the module and version for `airs-flex` offer must be provided. + instead of the one passed to the module and version for `airs-flex` offer must be provided. - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series Deployment Guide* as only a few selected sizes are supported. @@ -1203,7 +1203,10 @@ The basic Scale Set configuration properties are as follows: - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in `var.vnets`. - - `create_public_ip` - (`bool`, optional, defaults to module default) create Public IP for an interface. + - `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary one. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the interface. - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in the `var.loadbalancers` variable, network interface that has this property defined will be added to the Load Balancer's backend pool. @@ -1240,9 +1243,10 @@ map(object({ custom_id = optional(string) })) virtual_machine_scale_set = optional(object({ - size = optional(string) - zones = optional(list(string)) - disk_type = optional(string) + orchestration_type = optional(string) + size = optional(string) + zones = optional(list(string)) + disk_type = optional(string) bootstrap_options = optional(object({ type = optional(string) ip-address = optional(string) @@ -1302,16 +1306,20 @@ map(object({ webhooks_uris = optional(map(string), {}) }), {}) interfaces = list(object({ - name = string - subnet_key = string - create_public_ip = optional(bool) - pip_domain_name_label = optional(string) - pip_idle_timeout_in_minutes = optional(number) - pip_prefix_name = optional(string) - pip_prefix_resource_group_name = optional(string) - pip_prefix_id = optional(string) - load_balancer_key = optional(string) - application_gateway_key = optional(string) + name = string + subnet_key = string + ip_configurations = optional(map(object({ + name = optional(string) + primary = optional(bool, true) + create_public_ip = optional(bool, false) + pip_domain_name_label = optional(string) + pip_idle_timeout_in_minutes = optional(number) + pip_prefix_name = optional(string) + pip_prefix_resource_group_name = optional(string) + pip_prefix_id = optional(string) + }))) + load_balancer_key = optional(string) + application_gateway_key = optional(string) })) autoscaling_profiles = optional(list(object({ name = string diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_vwan.md b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_vwan.md new file mode 100644 index 000000000..5336c07c0 --- /dev/null +++ b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_vwan.md @@ -0,0 +1,1701 @@ +--- +hide_title: true +id: vmseries_transit_vnet_dedicated_vwan +keywords: +- pan-os +- panos +- firewall +- configuration +- terraform +- vmseries +- vm-series +- swfw +- software-firewalls +- azure +pagination_next: null +pagination_prev: null +sidebar_label: VM-Series Transit VNet Dedicated Vwan +title: 'Reference Architecture with Terraform: VM-Series in Azure, Centralized Architecture, + Dedicated Inbound NGFW Option' +--- + +# Reference Architecture with Terraform: VM-Series in Azure, Centralized Architecture, Dedicated Inbound NGFW Option + +Palo Alto Networks produces several +[validated reference architecture design and deployment documentation guides](https://www.paloaltonetworks.com/resources/reference-architectures), +which describe well-architected and tested deployments. When deploying VM-Series in a public cloud, the reference architectures +guide users toward the best security outcomes, whilst reducing rollout time and avoiding common integration efforts. + +The Terraform code presented here will deploy Palo Alto Networks VM-Series firewalls in Azure based on a centralized design with +dedicated-inbound VM-Series and integration with Azure Virtual WAN; for a discussion of other options, please see the design guide from +[the reference architecture guides](https://www.paloaltonetworks.com/resources/reference-architectures). + +[![GitHub Logo](/img/view_on_github.png)](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/tree/main/examples/vmseries_transit_vnet_dedicated_vwan) [![Terraform Logo](/img/view_on_terraform_registry.png)](https://registry.terraform.io/modules/PaloAltoNetworks/swfw-modules/azurerm/latest/examples/vmseries_transit_vnet_dedicated_vwan) + +## Reference Architecture Design + +![simple](aa2ae33a-fb46-4a1c-9811-98ea3b132297.png) + +This code implements: + +- a *centralized design*, a hub-and-spoke topology with a Transit VNet containing VM-Series to inspect all inbound, outbound, + east-west, and enterprise traffic +- the *dedicated inbound option*, which separates inbound traffic flows onto a separate set of VM-Series. + +## Detailed Architecture and Design + +### Centralized Design + +This design uses a Transit VNet. Application functions and resources are deployed across multiple VNets that are connected in +a hub-and-spoke topology. The hub of the topology, or transit VNet, is the central point of connectivity for all inbound, +outbound, east-west, and enterprise traffic. You deploy all VM-Series firewalls within the transit VNet. + +### Dedicated Inbound Option + +The dedicated inbound option separates traffic flows across two separate sets of VM-Series firewalls. One set of VM-Series +firewalls is dedicated to inbound traffic flows, allowing for greater flexibility and scaling of inbound traffic loads. +The second set of VM-Series firewalls services all outbound, east-west, and enterprise network traffic flows. This deployment +choice offers increased scale and operational resiliency and reduces the chances of high bandwidth use from the inbound traffic +flows affecting other traffic flows within the deployment. + +![Detailed Topology Diagram](2ef99143-3dcf-4113-814d-aedca8fcccf3.png) + +This reference architecture consists of: + +- a VNET containing: + - 3 subnets dedicated to the firewalls: management, private and public + - Route Tables and Network Security Groups +- 2 Load Balancers: + - public - with a public IP address assigned, in front of the firewalls public interfaces, for incoming traffic + - private - in front of the firewalls private interfaces, for outgoing and east-west traffic +- a Storage Account used to keep bootstrap packages containing `DAY0` configuration for the firewalls +- 4 firewalls: + - deployed in different zones + - 2 pairs, one for inbound, the other for outbound and east-west traffic + - with 3 network interfaces each: management, public, private + - with public IP addresses assigned to: + - management interface + - public interface +- a Virtual WAN containing: + - one Virtual Hub + - 2 connections to the Virtual Hub (one dedicated for spoke vnet and one dedicated for the transit vnet) +- _(optional)_ test workloads with accompanying infrastructure: + - 3 Spoke VNETs with Route Tables and Network Security Groups + - 3 Spoke VMs serving as WordPress-based web servers + - 3 Azure Bastion managed jump hosts + +**NOTE!** +- In order to deploy the architecture without test workloads described above, empty the `test_infrastructure` map in + `example.tfvars` file. + +## Prerequisites + +A list of requirements might vary depending on the platform used to deploy the infrastructure but a minimum one includes: + +- _(in case of non cloud shell deployment)_ credentials and (optionally) tools required to authenticate against Azure Cloud, see + [AzureRM provider documentation for details](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#authenticating-to-azure) +- [supported](#requirements) version of [`Terraform`]() +- if you have not run Palo Alto NGFW images in a subscription it might be necessary to accept the license first + ([see this note](../../modules/vmseries#accept-azure-marketplace-terms)) + +**Note!** +- after the deployment the firewalls remain not licensed, they do however contain minimum `DAY0` configuration (required NIC, VR, + routes configuration). +- this example contains some **files** that **can contain sensitive data**. Keep in mind that **this code** is + **only an example**. It's main purpose is to introduce the Terraform modules. + +## Usage + +### Deployment Steps + +- checkout the code locally (if you haven't done so yet) +- copy the [`example.tfvars`](./example.tfvars) file, rename it to `terraform.tfvars` and adjust it to your needs (take a closer + look at the `TODO` markers) +- copy the [`init-cfg.sample.txt`](./files/init-cfg.sample.txt) to `init-cfg.txt` and fill it out with required bootstrap + parameters (see this [documentation](https://docs.paloaltonetworks.com/vm-series/9-1/vm-series-deployment/bootstrap-the-vm-series-firewall/create-the-init-cfgtxt-file/init-cfgtxt-file-components#id07933d91-15be-414d-bc8d-f2a5f3d8df6b) for details) +- _(optional)_ authenticate to AzureRM, switch to the Subscription of your choice +- provide `subscription_id` either by creating an environment variable named `ARM_SUBSCRIPTION_ID` with Subscription ID as value + in your shell (recommended option) or by setting the value of `subscription_id` variable within your `tfvars` file (discouraged + option, we don't recommend putting the Subscription ID in clear text inside the code). +- initialize the Terraform module: + + ```bash + terraform init + ``` + +- _(optional)_ plan you infrastructure to see what will be actually deployed: + + ```bash + terraform plan + ``` + +- deploy the infrastructure (you will have to confirm it with typing in `yes`): + + ```bash + terraform apply + ``` + + The deployment takes couple of minutes. Observe the output. At the end you should see a summary similar to this: + + ```console + bootstrap_storage_urls = + lb_frontend_ips = { + "private" = { + "ha-ports" = "1.2.3.4" + } + "public" = { + "palo-lb-app1-pip" = "1.2.3.4" + } + } + password = + username = "panadmin" + vmseries_mgmt_ips = { + "fw-in-1" = "1.2.3.4" + "fw-in-2" = "1.2.3.4" + "fw-obew-1" = "1.2.3.4" + "fw-obew-2" = "1.2.3.4" + } + ``` + +- at this stage you have to wait couple of minutes for the firewalls to bootstrap. + +### Post deploy + +Firewalls in this example are configured with password authentication. To retrieve the initial credentials run: + +- for username: + + ```bash + terraform output usernames + ``` + +- for password: + + ```bash + terraform output passwords + ``` + +The management public IP addresses are available in the `vmseries_mgmt_ips`: + +```bash +terraform output vmseries_mgmt_ips +``` + +You can now login to the devices using either: + +- cli - ssh client is required +- Web UI (https) - any modern web browser, note that initially the traffic is encrypted with a self-signed certificate. + +As mentioned, the devices already contain `DAY0` configuration, so all network interfaces should be configured and Azure Load +Balancer should already report that the devices are healthy. + +You can now proceed with licensing the devices and configuring your first rules. + +Please also refer to [this repository](https://github.com/PaloAltoNetworks/iron-skillet) for `DAY1` configuration +(security hardening). + +### Cleanup + +To remove the deployed infrastructure run: + +```bash +terraform destroy +``` + +## Reference + +### Requirements + +- `terraform`, version: >= 1.5, < 2.0 + +### Providers + +- `random` +- `local` +- `azurerm` + +### Modules +Name | Version | Source | Description +--- | --- | --- | --- +`vnet` | - | ../../modules/vnet | +`vnet_peering` | - | ../../modules/vnet_peering | +`public_ip` | - | ../../modules/public_ip | +`natgw` | - | ../../modules/natgw | +`load_balancer` | - | ../../modules/loadbalancer | +`appgw` | - | ../../modules/appgw | +`ngfw_metrics` | - | ../../modules/ngfw_metrics | +`bootstrap` | - | ../../modules/bootstrap | +`vmseries` | - | ../../modules/vmseries | +`virtual_wan` | - | ../../modules/vwan | +`test_infrastructure` | - | ../../modules/test_infrastructure | + +### Resources + +- `availability_set` (managed) +- `resource_group` (managed) +- `file` (managed) +- `password` (managed) +- `resource_group` (data) + +### Required Inputs + +Name | Type | Description +--- | --- | --- +[`subscription_id`](#subscription_id) | `string` | Azure Subscription ID is a required argument since AzureRM provider v4. +[`resource_group_name`](#resource_group_name) | `string` | Name of the Resource Group. +[`region`](#region) | `string` | The Azure region to use. +[`vnets`](#vnets) | `map` | A map defining VNETs. + +### Optional Inputs + +Name | Type | Description +--- | --- | --- +[`name_prefix`](#name_prefix) | `string` | A prefix that will be added to all created resources. +[`create_resource_group`](#create_resource_group) | `bool` | When set to `true` it will cause a Resource Group creation. +[`tags`](#tags) | `map` | Map of tags to assign to the created resources. +[`vnet_peerings`](#vnet_peerings) | `map` | A map defining VNET peerings. +[`public_ips`](#public_ips) | `object` | A map defining Public IP Addresses and Prefixes. +[`natgws`](#natgws) | `map` | A map defining NAT Gateways. +[`virtual_wans`](#virtual_wans) | `map` | A map defining Virtual WANs. +[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (both private and public) Load Balancers. +[`appgws`](#appgws) | `map` | A map defining all Application Gateways in the current deployment. +[`availability_sets`](#availability_sets) | `map` | A map defining availability sets. +[`ngfw_metrics`](#ngfw_metrics) | `object` | A map controlling metrics-relates resources. +[`bootstrap_storages`](#bootstrap_storages) | `map` | A map defining Azure Storage Accounts used to host file shares for bootstrapping NGFWs. +[`vmseries_universal`](#vmseries_universal) | `object` | A map defining common settings for all created VM-Series instances. +[`vmseries`](#vmseries) | `map` | A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image. +[`test_infrastructure`](#test_infrastructure) | `map` | A map defining test infrastructure including test VMs and Azure Bastion hosts. + +### Outputs + +Name | Description +--- | --- +`usernames` | Initial administrative username to use for VM-Series. +`passwords` | Initial administrative password to use for VM-Series. +`natgw_public_ips` | Nat Gateways Public IP resources. +`metrics_instrumentation_keys` | The Instrumentation Key of the created instance(s) of Azure Application Insights. +`lb_frontend_ips` | IP Addresses of the load balancers. +`vmseries_mgmt_ips` | IP addresses for the VM-Series management interface. +`bootstrap_storage_urls` | +`test_vms_usernames` | Initial administrative username to use for test VMs. +`test_vms_passwords` | Initial administrative password to use for test VMs. +`test_vms_ips` | IP Addresses of the test VMs. +`test_lb_frontend_ips` | IP Addresses of the test load balancers. + +### Required Inputs details + +#### subscription_id + +Azure Subscription ID is a required argument since AzureRM provider v4. + +**Note!** \ +Instead of putting the Subscription ID directly in the code, it's recommended to use an environment variable. Create an +environment variable named `ARM_SUBSCRIPTION_ID` with your Subscription ID as value and leave this variable set to `null`. + + +Type: string + +[back to list](#modules-required-inputs) + +#### resource_group_name + +Name of the Resource Group. + +Type: string + +[back to list](#modules-required-inputs) + +#### region + +The Azure region to use. + +Type: string + +[back to list](#modules-required-inputs) + +#### vnets + +A map defining VNETs. + +For detailed documentation on each property refer to [module documentation](../../modules/vnet) + +- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. +- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. +- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. +- `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. +- `dns_servers` - (`list`, optional, defaults to module defaults) a list of IP addresses of custom DNS servers + (by default Azure DNS is used). +- `vnet_encryption` - (`string`, optional, defaults to module default) enables Azure Virtual Network Encryption when + set, only possible value at the moment is `AllowUnencrypted`. When set to `null`, the feature is + disabled. +- `ddos_protection_plan_id` - (`string`, optional, defaults to `null`) ID of an existing Azure Network DDOS Protection Plan to + be associated with the VNET. +- `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see + [VNET module documentation](../../modules/vnet#network_security_groups). +- `route_tables` - (`map`, optional) map of Route Tables to create, for details see + [VNET module documentation](../../modules/vnet#route_tables). +- `subnets` - (`map`, optional) map of Subnets to create or source, for details see + [VNET module documentation](../../modules/vnet#subnets). + + +Type: + +```hcl +map(object({ + create_virtual_network = optional(bool, true) + name = string + resource_group_name = optional(string) + address_space = optional(list(string)) + dns_servers = optional(list(string)) + vnet_encryption = optional(string) + ddos_protection_plan_id = optional(string) + network_security_groups = optional(map(object({ + name = string + rules = optional(map(object({ + name = string + priority = number + direction = string + access = string + protocol = string + source_port_range = optional(string) + source_port_ranges = optional(list(string)) + destination_port_range = optional(string) + destination_port_ranges = optional(list(string)) + source_address_prefix = optional(string) + source_address_prefixes = optional(list(string)) + destination_address_prefix = optional(string) + destination_address_prefixes = optional(list(string)) + })), {}) + })), {}) + route_tables = optional(map(object({ + name = string + bgp_route_propagation_enabled = optional(bool) + routes = map(object({ + name = string + address_prefix = string + next_hop_type = string + next_hop_ip_address = optional(string) + })) + })), {}) + subnets = optional(map(object({ + create = optional(bool, true) + name = string + address_prefixes = optional(list(string), []) + network_security_group_key = optional(string) + route_table_key = optional(string) + default_outbound_access_enabled = optional(bool) + enable_storage_service_endpoint = optional(bool) + enable_appgw_delegation = optional(bool) + enable_cloudngfw_delegation = optional(bool) + })), {}) + })) +``` + + +[back to list](#modules-required-inputs) + +### Optional Inputs details + +#### name_prefix + +A prefix that will be added to all created resources. +There is no default delimiter applied between the prefix and the resource name. +Please include the delimiter in the actual prefix. + +Example: +``` +name_prefix = "test-" +``` + +**Note!** \ +This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, +even if it is also prefixed with the same value as the one in this property. + + +Type: string + +Default value: `` + +[back to list](#modules-optional-inputs) + +#### create_resource_group + +When set to `true` it will cause a Resource Group creation. +Name of the newly specified RG is controlled by `resource_group_name`. + +When set to `false` the `resource_group_name` parameter is used to specify a name of an existing Resource Group. + + +Type: bool + +Default value: `true` + +[back to list](#modules-optional-inputs) + +#### tags + +Map of tags to assign to the created resources. + +Type: map(string) + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### vnet_peerings + +A map defining VNET peerings. + +Following properties are supported: +- `local_vnet_name` - (`string`, required) name of the local VNET. +- `local_resource_group_name` - (`string`, optional) name of the resource group, in which local VNET exists. +- `remote_vnet_name` - (`string`, required) name of the remote VNET. +- `remote_resource_group_name` - (`string`, optional) name of the resource group, in which remote VNET exists. + + +Type: + +```hcl +map(object({ + local_vnet_name = string + local_resource_group_name = optional(string) + remote_vnet_name = string + remote_resource_group_name = optional(string) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### public_ips + +A map defining Public IP Addresses and Prefixes. + +Following properties are available: + +- `public_ip_addresses` - (`map`, optional) map of objects describing Public IP Addresses, please refer to + [module documentation](../../modules/public_ip#public_ip_addresses) + for available properties. +- `public_ip_prefixes` - (`map`, optional) map of objects describing Public IP Prefixes, please refer to + [module documentation](../../modules/public_ip#public_ip_prefixes) + for available properties. + + +Type: + +```hcl +object({ + public_ip_addresses = optional(map(object({ + create = bool + name = string + resource_group_name = optional(string) + zones = optional(list(string)) + domain_name_label = optional(string) + idle_timeout_in_minutes = optional(number) + prefix_name = optional(string) + prefix_resource_group_name = optional(string) + prefix_id = optional(string) + })), {}) + public_ip_prefixes = optional(map(object({ + create = bool + name = string + resource_group_name = optional(string) + zones = optional(list(string)) + length = optional(number) + })), {}) + }) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### natgws + +A map defining NAT Gateways. + +Please note that a NAT Gateway is a zonal resource, this means it's always placed in a zone (even when you do not specify one +explicitly). Please refer to Microsoft documentation for notes on NAT Gateway's zonal resiliency. +For detailed documentation on each property refer to [module documentation](../../modules/natgw). + +Following properties are supported: +- `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full + resource name, including prefixes. +- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this + NAT Gateway will be assigned to. +- `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, + defined in `var.vnets` for a VNET described by `vnet_name`. +- `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), + created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. +- `resource_group_name` - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing + one). +- `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped + Azure will pick a zone. +- `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. +- `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. +- `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. + +Example: +``` +natgws = { + "natgw" = { + name = "natgw" + vnet_key = "transit-vnet" + subnet_keys = ["management"] + public_ip = { + create = true + name = "natgw-pip" + } + } +} +``` + + +Type: + +```hcl +map(object({ + name = string + vnet_key = string + subnet_keys = list(string) + create_natgw = optional(bool, true) + resource_group_name = optional(string) + zone = optional(string) + idle_timeout = optional(number, 4) + public_ip = optional(object({ + create = bool + name = optional(string) + resource_group_name = optional(string) + key = optional(string) + })) + public_ip_prefix = optional(object({ + create = bool + name = optional(string) + resource_group_name = optional(string) + length = optional(number) + key = optional(string) + })) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### virtual_wans + +A map defining Virtual WANs. + +For detailed documentation on each property refer to [module documentation](../../modules/vwan) + +- `create` - (`bool`, optional, defaults to `true`) when set to `true` will create a new Virtual WAN, + `false` will source an existing Virtual WAN. +- `name` - (`string`, required) a name of a Virtual WAN. In case `create = false` this should be a + full resource name, including prefixes. +- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which + the Virtual WAN will reside or is sourced from. +- `disable_vpn_encryption` - (`bool`, optional, defaults to `false`) if `true`, VPN encryption is disabled. +- `allow_branch_to_branch_traffic` - (`bool`, optional, defaults to `true`) if `false`, branch-to-branch traffic is not allowed. +- `virtual_hubs` - (`map`, optional) map of Virtual Hubs to create or source, for details see + [Virtual WAN module documentation](../../modules/vwan#virtual_hubs). + + +Type: + +```hcl +map(object({ + name = string + resource_group_name = optional(string) + create = optional(bool, true) + region = optional(string) + disable_vpn_encryption = optional(bool, false) + allow_branch_to_branch_traffic = optional(bool, true) + virtual_hubs = optional(map(object({ + name = string + address_prefix = string + create = optional(bool, true) + resource_group_name = optional(string) + region = optional(string) + hub_routing_preference = optional(string) + virtual_router_auto_scale_min_capacity = optional(number) + connections = optional(map(object({ + name = string + connection_type = string + remote_virtual_network_key = optional(string) + internet_security_enabled = optional(bool) + vpn_site_key = optional(string) + vpn_link = optional(list(object({ + vpn_link_name = string + vpn_site_link_key = string + bandwidth_mbps = optional(number) + bgp_enabled = optional(bool) + connection_mode = optional(string) + protocol = optional(string) + ratelimit_enabled = optional(bool) + shared_key = optional(string) + local_azure_ip_address_enabled = optional(bool) + ipsec_policy = optional(object({ + dh_group = optional(string) + ike_encryption_algorithm = optional(string) + ike_integrity_algorithm = optional(string) + encryption_algorithm = optional(string) + integrity_algorithm = optional(string) + pfs_group = optional(string) + sa_data_size_kb = optional(number) + sa_lifetime_sec = optional(number) + })) + }))) + routing = optional(object({ + associated_route_table_key = optional(string) + propagated_route_table_keys = optional(list(string)) + propagated_route_table_labels = optional(set(string)) + static_vnet_route_name = optional(string) + static_vnet_route_address_prefixes = optional(set(string)) + static_vnet_route_next_hop_ip_address = optional(string) + static_vnet_local_route_override_criteria = optional(string) + })) + })), {}) + route_tables = optional(map(object({ + name = string + labels = optional(set(string)) + routes = optional(map(object({ + name = string + destinations_type = string + destinations = list(string) + next_hop_type = optional(string) + next_hop_key = string + })), {}) + })), {}) + routing_intent = optional(object({ + routing_intent_name = string + routing_policy = list(object({ + routing_policy_name = string + destinations = list(string) + next_hop_key = string + })) + })) + vpn_gateway = optional(object({ + name = string + resource_group_name = optional(string) + scale_unit = optional(number) + routing_preference = optional(string) + }), null) + vpn_sites = optional(map(object({ + name = string + region = optional(string) + resource_group_name = optional(string) + address_cidrs = optional(set(string)) + link = optional(map(object({ + name = string + ip_address = optional(string) + fqdn = optional(string) + provider_name = optional(string) + speed_in_mbps = optional(number, 0) + }))) + })), {}) + })), {}) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### load_balancers + +A map containing configuration for all (both private and public) Load Balancers. + +This is a brief description of available properties. For a detailed one please refer to +[module documentation](../../modules/loadbalancer). + +Following properties are available: + +- `name` - (`string`, required) a name of the Load Balancer. +- `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` + map that stores the Subnet described by `subnet_key`. +- `zones` - (`list`, optional, defaults to ["1", "2", "3"]) a list of zones for Load Balancer's frontend IP + configurations. +- `backend_name` - (`string`, optional, defaults to "vmseries_backend") a name of the backend pool to create. +- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to + [module documentation](../../modules/loadbalancer#health_probes) for more specific use + cases and available properties. +- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. + +- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer#frontend_ips) for available + properties. + + **Note!** \ + In this example the `subnet_id` is not available directly, another property has been introduced instead: + + - `subnet_key` - (`string`, optional, defaults to `null`) a key pointing to a Subnet definition in the `var.vnets` map. + + +Type: + +```hcl +map(object({ + name = string + vnet_key = optional(string) + zones = optional(list(string), ["1", "2", "3"]) + backend_name = optional(string, "vmseries_backend") + health_probes = optional(map(object({ + name = string + protocol = string + port = optional(number) + probe_threshold = optional(number) + interval_in_seconds = optional(number) + request_path = optional(string) + }))) + nsg_auto_rules_settings = optional(object({ + nsg_name = optional(string) + nsg_vnet_key = optional(string) + nsg_key = optional(string) + nsg_resource_group_name = optional(string) + source_ips = list(string) + base_priority = optional(number) + })) + frontend_ips = optional(map(object({ + name = string + subnet_key = optional(string) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + public_ip_prefix_key = optional(string) + private_ip_address = optional(string) + gwlb_key = optional(string) + in_rules = optional(map(object({ + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + })), {}) + out_rules = optional(map(object({ + name = string + protocol = string + allocated_outbound_ports = optional(number) + enable_tcp_reset = optional(bool) + idle_timeout_in_minutes = optional(number) + })), {}) + })), {}) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### appgws + +A map defining all Application Gateways in the current deployment. + +For detailed documentation on how to configure this resource, for available properties, especially for the defaults, +refer to [module documentation](../../modules/appgw). + +**Note!** \ +The `rules` property is meant to bind together `backend_setting`, `redirect` or `url_path_map` (all 3 are mutually exclusive). +It represents the Rules section of an Application Gateway in Azure Portal. + +Below you can find a brief list of most important properties: + +- `name` - (`string`, required) the name of the Application Gateway, will be prefixed with `var.name_prefix`. +- `vnet_key` - (`string`, required) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet + described by `subnet_key`. +- `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an + Application Gateway V2 dedicated subnet. +- `zones` - (`list`, optional, defaults to `["1", "2", "3"]`) parameter controlling if this is a zonal, or a + non-zonal deployment. +- `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created + Public IP will have it's name prefixes with `var.name_prefix`. +- `listeners` - (`map`, required) defines Application Gateway's Listeners, see + [module's documentation](../../modules/appgw#listeners) for details. +- `backend_pool` - (`map`, optional, defaults to module default) backend pool definition, when skipped an empty backend + will be created. +- `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend + settings, see [module's documentation](../../modules/appgw#backend_settings) for details. +- `probes` - (`map`, optional, defaults to module default) defines backend probes used check health of backends, see + [module's documentation](../../modules/appgw#probes) for details. +- `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see + [module's documentation](../../modules/appgw#rewrites) for details. +- `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects + definition, see [module's documentation](../../modules/appgw#redirects) for details. +- `url_path_maps` - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, + see [module's documentation](../../modules/appgw#url_path_maps) for details. +- `rules` - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either + `backend_setting`, `redirect` or `url_path_map`, see + [module's documentation](../../modules/appgw#rules) for details. + + +Type: + +```hcl +map(object({ + name = string + vnet_key = string + subnet_key = string + zones = optional(list(string), ["1", "2", "3"]) + public_ip = object({ + create = optional(bool, true) + name = optional(string) + resource_group_name = optional(string) + key = optional(string) + }) + domain_name_label = optional(string) + capacity = optional(object({ + static = optional(number) + autoscale = optional(object({ + min = number + max = number + })) + })) + enable_http2 = optional(bool) + waf = optional(object({ + prevention_mode = bool + rule_set_type = optional(string) + rule_set_version = optional(string) + })) + managed_identities = optional(list(string)) + global_ssl_policy = optional(object({ + type = optional(string) + name = optional(string) + min_protocol_version = optional(string) + cipher_suites = optional(list(string)) + })) + ssl_profiles = optional(map(object({ + name = string + ssl_policy_name = optional(string) + ssl_policy_min_protocol_version = optional(string) + ssl_policy_cipher_suites = optional(list(string)) + }))) + frontend_ip_configuration_name = optional(string, "public_ipconfig") + listeners = map(object({ + name = string + port = number + protocol = optional(string) + host_names = optional(list(string)) + ssl_profile_name = optional(string) + ssl_certificate_path = optional(string) + ssl_certificate_pass = optional(string) + ssl_certificate_vault_id = optional(string) + custom_error_pages = optional(map(string)) + })) + backend_pool = optional(object({ + name = optional(string) + vmseries_ips = optional(list(string)) + })) + backend_settings = optional(map(object({ + name = string + port = number + protocol = string + path = optional(string) + hostname_from_backend = optional(string) + hostname = optional(string) + timeout = optional(number) + use_cookie_based_affinity = optional(bool) + affinity_cookie_name = optional(string) + probe_key = optional(string) + root_certs = optional(map(object({ + name = string + path = string + }))) + }))) + probes = optional(map(object({ + name = string + path = string + host = optional(string) + port = optional(number) + protocol = optional(string) + interval = optional(number) + timeout = optional(number) + threshold = optional(number) + match_code = optional(list(number)) + match_body = optional(string) + }))) + rewrites = optional(map(object({ + name = optional(string) + rules = optional(map(object({ + name = string + sequence = number + conditions = optional(map(object({ + pattern = string + ignore_case = optional(bool) + negate = optional(bool) + }))) + request_headers = optional(map(string)) + response_headers = optional(map(string)) + }))) + }))) + redirects = optional(map(object({ + name = string + type = string + target_listener_key = optional(string) + target_url = optional(string) + include_path = optional(bool) + include_query_string = optional(bool) + }))) + url_path_maps = optional(map(object({ + name = string + backend_key = string + path_rules = optional(map(object({ + paths = list(string) + backend_key = optional(string) + redirect_key = optional(string) + }))) + }))) + rules = map(object({ + name = string + priority = number + backend_key = optional(string) + listener_key = string + rewrite_key = optional(string) + url_path_map_key = optional(string) + redirect_key = optional(string) + })) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### availability_sets + +A map defining availability sets. Can be used to provide infrastructure high availability when zones cannot be used. + +Following properties are supported: + +- `name` - (`string`, required) name of the Application Insights. +- `update_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of update domains that are used. +- `fault_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of fault domains that are used. + +**Note!** \ +Please keep in mind that Azure defaults are not working for every region (especially the small ones, without any Availability +Zones). Please verify how many update and fault domain are supported in a region before deploying this resource. + + +Type: + +```hcl +map(object({ + name = string + update_domain_count = optional(number) + fault_domain_count = optional(number) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### ngfw_metrics + +A map controlling metrics-relates resources. + +When set to explicit `null` (default) it will disable any metrics resources in this deployment. + +When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each +Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will +be derived from the Scale Set name and suffixed with `-ai`. + +All the settings available below are common to the Log Analytics Workspace and Application Insight instances. + +Following properties are available: + +- `name` - (`string`, required) name of the (common) Log Analytics Workspace. +- `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log + Analytics Workspace. +- `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting + the Log Analytics Workspace. +- `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. +- `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. + + +Type: + +```hcl +object({ + name = string + create_workspace = optional(bool, true) + resource_group_name = optional(string) + sku = optional(string) + metrics_retention_in_days = optional(number) + }) +``` + + +Default value: `&{}` + +[back to list](#modules-optional-inputs) + +#### bootstrap_storages + +A map defining Azure Storage Accounts used to host file shares for bootstrapping NGFWs. + +You can create or re-use an existing Storage Account and/or File Share. For details on all available properties please refer to +[module's documentation](../../modules/bootstrap). Following is just an extract of the most important ones: + +- `name` - (`string`, required) name of the Storage Account that will be created or sourced. + + **Note** \ + For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ + Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case letters + and numbers. + +- `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or + will host (created) a Storage Account. When skipped the code will fall back to + `var.resource_group_name`. +- `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration. + + The property you should pay attention to is: + + - `create` - (`bool`, optional, defaults to module default) controls if the Storage Account specified in the `name` property + will be created or sourced. + + For detailed documentation see [module's documentation](../../modules/bootstrap#storage_account). + +- `storage_network_security` - (`map`, optional, defaults to `{}`) a map defining network security settings for a **new** + storage account. + + The properties you should pay attention to are: + + - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the + `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to work + they also need to have the Storage Account Service Endpoint enabled. + - `vnet_key` - (`string`, optional) a key pointing to a VNET definition in the `var.vnets` map that stores the + Subnets described in `allowed_subnet_keys`. + + For detailed documentation see [module's documentation](../../modules/bootstrap#storage_network_security). + +- `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. + + The properties you should pay attention to are: + + - `create_file_shares` - (`bool`, optional, defaults to module default) controls if the File Shares defined in the + `file_shares` property will be created or sourced. + - `disable_package_dirs_creation` - (`bool`, optional, defaults to module default) for sourced File Shares, controls if the + bootstrap package folder structure will be created. + + For detailed documentation see [module's documentation](../../modules/bootstrap#file_shares_configuration). + +- `file_shares` - (`map`, optional, defaults to `{}`) a map that holds File Shares and bootstrap package + configuration. For detailed description see + [module's documentation](../../modules/bootstrap#file_shares). + + +Type: + +```hcl +map(object({ + name = string + resource_group_name = optional(string) + storage_account = optional(object({ + create = optional(bool) + replication_type = optional(string) + kind = optional(string) + tier = optional(string) + blob_retention = optional(number) + }), {}) + storage_network_security = optional(object({ + min_tls_version = optional(string) + allowed_public_ips = optional(list(string)) + vnet_key = optional(string) + allowed_subnet_keys = optional(list(string), []) + }), {}) + file_shares_configuration = optional(object({ + create_file_shares = optional(bool) + disable_package_dirs_creation = optional(bool) + quota = optional(number) + access_tier = optional(string) + }), {}) + file_shares = optional(map(object({ + name = string + bootstrap_package_path = optional(string) + bootstrap_files = optional(map(string)) + bootstrap_files_md5 = optional(map(string)) + quota = optional(number) + access_tier = optional(string) + })), {}) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### vmseries_universal + +A map defining common settings for all created VM-Series instances. + +It duplicates popular properties from `vmseries` variable, specifically `vmseries.image` and `vmseries.virtual_machine` maps. +However, if values are set in those maps, they still take precedence over the ones set within this variable. As a result, all +universal properties can be overriden on a per-VM basis. + +Following properties are supported: + +- `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used + instead of the one passed to the module and version for `airs-flex` offer must be provided. +- `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. +- `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. +- `bootstrap_options` - (`map`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS + when launched for the 1st time, for details see module documentation. +- `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the bootstrap + package. For details and available properties refer to `vmseries` variable. + + +Type: + +```hcl +object({ + use_airs = optional(bool) + version = optional(string) + size = optional(string) + bootstrap_options = optional(object({ + type = optional(string) + ip-address = optional(string) + default-gateway = optional(string) + netmask = optional(string) + ipv6-address = optional(string) + ipv6-default-gateway = optional(string) + hostname = optional(string) + panorama-server = optional(string) + panorama-server-2 = optional(string) + tplname = optional(string) + dgname = optional(string) + cgname = optional(string) + dns-primary = optional(string) + dns-secondary = optional(string) + vm-auth-key = optional(string) + op-command-modes = optional(string) + op-cmd-dpdk-pkt-io = optional(string) + plugin-op-commands = optional(string) + dhcp-send-hostname = optional(string) + dhcp-send-client-id = optional(string) + dhcp-accept-server-hostname = optional(string) + dhcp-accept-server-domain = optional(string) + vm-series-auto-registration-pin-id = optional(string) + vm-series-auto-registration-pin-value = optional(string) + auth-key = optional(string) + authcodes = optional(string) + })) + bootstrap_package = optional(object({ + bootstrap_storage_key = string + static_files = optional(map(string), {}) + bootstrap_package_path = optional(string) + bootstrap_xml_template = optional(string) + private_snet_key = optional(string) + public_snet_key = optional(string) + ai_update_interval = optional(number, 5) + intranet_cidr = optional(string) + })) + }) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### vmseries + +A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image. + +For details and defaults for available options please refer to the [`vmseries`](../../modules/vmseries) module. + +The most basic properties are as follows: + +- `name` - (`string`, required) name of the VM, will be prefixed with the value of `var.name_prefix`. +- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to + deploy network interfaces for deployed VM. +- `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VM. + + The `authentication` property is optional and holds the firewall admin access details. By default, standard username + `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). + + **Note!** \ + The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have + to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to + `true`, then you have to specify `ssh_keys` property. + + For all properties and their default values see [module's documentation](../../modules/vmseries#authentication). + +- `image` - (`map`, optional) properties defining a base image used by the deployed VM. The `image` property is + required (if no common properties were set within `vmseries_universal` variable) but there are only 2 + properties (mutually exclusive) that have to be set, either: + + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. + + For details on all properties refer to [module's documentation](../../modules/vmseries#image). + +- `virtual_machine` - (`map`, optional, defaults to module default) a map that groups most common VM configuration options. + Most common properties are: + + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zone` - (`string`, required) the Availability Zone in which the VM and (if deployed) public IP addresses will + be created. + - `disk_type` - (`string`, optional, defaults to module default) type of a Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `size` values). + - `bootstrap_options` - (`map`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS + when launched for the 1st time, for details see module documentation. + - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the + bootstrap package. + + **Note!** \ + At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a combination + of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details on the other + properties see the [`bootstrap` module documentation](../../modules/bootstrap). + + Following properties are available: + + - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that + will host bootstrap packages. Each package will be hosted on a separate File Share. The File + Shares will be created automatically, one for each firewall. + - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File + Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap#file_shares) + property documentation for details. + - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap + package. + - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this example + is using full bootstrap method, the sample templates are in [`templates`](./templates) folder. + + The templates are used to provide `day0` like configuration which consists of: + + - network interfaces configuration. + - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes + required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow + Inbound and OBEW traffic. + - *any-any* security rule. + - an outbound NAT rule that will allow the Outbound traffic to flow to the Internet. + + **Note!** \ + Day0 configuration is **not meant** to be **secure**. It's here merely to help with the basic firewall setup. When + `bootstrap_xml_template` is set, one of the following properties might be required. + + - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a private + Load Balancer health checks and for Inbound traffic. + - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a public + Load Balancer health checks and for Outbound traffic. + - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when + `ngfw_metrics` module is defined and used in this example. The Application Insights + Instrumentation Key will be populated automatically. + - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all + private networks. When set it will override the private Subnet CIDR for inbound traffic + static routes. + + For details on all properties refer to [module's documentation](../../modules/vmseries#virtual_machine). + +- `interfaces` - (`list`, required) configuration of all network interfaces. Order of the interfaces does matter - the + 1st interface is the management one. Most common properties are: + + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. + - `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary one. + **Note!** When you define multiple IP configurations, exactly one must be the primary. + - `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. When + skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is guarantied not + to change as long as the VM is running. Any stop/deallocate/restart operation might cause + the IP to change. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the interface. + - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` + variable, network interface that has this property defined will be added to the Load Balancer's + backend pool. + - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` + variable, network interface that has this property defined will be added to the Application + Gateway's backend pool. Mutually exclusive with `appgw_backend_pool_id`. + - `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of the Application Gateway backend pool to which + the network interface will be added. Mutually exclusive with `application_gateway_key`. + + For details on all properties refer to [module's documentation](../../modules/panorama#interfaces). + + +Type: + +```hcl +map(object({ + name = string + vnet_key = string + authentication = optional(object({ + username = optional(string, "panadmin") + password = optional(string) + disable_password_authentication = optional(bool, false) + ssh_keys = optional(list(string), []) + }), {}) + image = optional(object({ + use_airs = optional(bool) + version = optional(string) + publisher = optional(string) + offer = optional(string) + sku = optional(string) + enable_marketplace_plan = optional(bool) + custom_id = optional(string) + })) + virtual_machine = object({ + size = optional(string) + bootstrap_options = optional(object({ + type = optional(string) + ip-address = optional(string) + default-gateway = optional(string) + netmask = optional(string) + ipv6-address = optional(string) + ipv6-default-gateway = optional(string) + hostname = optional(string) + panorama-server = optional(string) + panorama-server-2 = optional(string) + tplname = optional(string) + dgname = optional(string) + cgname = optional(string) + dns-primary = optional(string) + dns-secondary = optional(string) + vm-auth-key = optional(string) + op-command-modes = optional(string) + op-cmd-dpdk-pkt-io = optional(string) + plugin-op-commands = optional(string) + dhcp-send-hostname = optional(string) + dhcp-send-client-id = optional(string) + dhcp-accept-server-hostname = optional(string) + dhcp-accept-server-domain = optional(string) + vm-series-auto-registration-pin-id = optional(string) + vm-series-auto-registration-pin-value = optional(string) + auth-key = optional(string) + authcodes = optional(string) + })) + bootstrap_package = optional(object({ + bootstrap_storage_key = string + static_files = optional(map(string), {}) + bootstrap_package_path = optional(string) + bootstrap_xml_template = optional(string) + private_snet_key = optional(string) + public_snet_key = optional(string) + ai_update_interval = optional(number, 5) + intranet_cidr = optional(string) + })) + zone = string + disk_type = optional(string) + disk_name = optional(string) + avset_key = optional(string) + capacity_reservation_group_id = optional(string) + accelerated_networking = optional(bool) + allow_extension_operations = optional(bool) + encryption_at_host_enabled = optional(bool) + disk_encryption_set_id = optional(string) + enable_boot_diagnostics = optional(bool, true) + boot_diagnostics_storage_uri = optional(string) + identity_type = optional(string) + identity_ids = optional(list(string)) + }) + interfaces = list(object({ + name = string + subnet_key = string + ip_configurations = map(object({ + name = optional(string) + primary = optional(bool, true) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + private_ip_address = optional(string) + })) + load_balancer_key = optional(string) + application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) + })) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### test_infrastructure + +A map defining test infrastructure including test VMs and Azure Bastion hosts. + +For details and defaults for available options please refer to the +[`test_infrastructure`](../../modules/test_infrastructure) module. + +Following properties are supported: + +- `create_resource_group` - (`bool`, optional, defaults to `true`) when set to `true`, a new Resource Group is created. When + set to `false`, an existing Resource Group is sourced. +- `resource_group_name` - (`string`, optional) name of the Resource Group to be created or sourced. +- `vnets` - (`map`, required) a map defining VNETs and peerings for the test environment. The most basic + properties are as follows: + + - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, + `false` will source an existing VNET. + - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = `false` this should be + a full resource name, including prefixes. + - `address_space` - (`list(string)`, required when `create_virtual_network = `false`) a list of CIDRs for a newly + created VNET. + - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see + [VNET module documentation](../../modules/vnet#network_security_groups). + - `route_tables` - (`map`, optional) map of Route Tables to create, for details see + [VNET module documentation](../../modules/vnet#route_tables). + - `subnets` - (`map`, optional) map of Subnets to create or source, for details see + [VNET module documentation](../../modules/vnet#subnets). + - `local_peer_config` - (`map`, optional) a map that contains local peer configuration parameters. This value allows to + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the local VNet peering. + - `remote_peer_config` - (`map`, optional) a map that contains remote peer configuration parameters. This value allows to + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the remote VNet peering. + + For all properties and their default values see [module's documentation](../../modules/test_infrastructure#vnets). + +- `load_balancers` - (`map`, optional) a map containing configuration for all (both private and public) Load Balancers. + The most basic properties are as follows: + + - `name` - (`string`, required) a name of the Load Balancer. + - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` + map that stores the Subnet described by `subnet_key`. + - `zones` - (`list`, optional, defaults to ["1", "2", "3"]) a list of zones for Load Balancer's frontend IP + configurations. + - `backend_name` - (`string`, optional) a name of the backend pool to create. + - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to + [loadbalancer module documentation](../../modules/loadbalancer#health_probes) for + more specific use cases and available properties. + - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that + will be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [loadbalancer module documentation](../../modules/loadbalancer#nsg_auto_rules_settings) + for available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. + + - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [loadbalancer module documentation](../../modules/loadbalancer#frontend_ips) for + available properties. + + **Note!** \ + In this example the `subnet_id` is not available directly, another property has been introduced instead: + + - `subnet_key` - (`string`, optional, defaults to `null`) a key pointing to a Subnet definition in the `var.vnets` map. + + For all properties and their default values see + [module's documentation](../../modules/test_infrastructure#load_balancers). + +- `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VMs. +- `spoke_vms` - (`map`, required) a map defining test VMs. The most basic properties are as follows: + + - `name` - (`string`, required) a name of the VM. + - `vnet_key` - (`string`, required) a key describing a VNET defined in `vnets` property. + - `subnet_key` - (`string`, required) a key describing a Subnet found in a VNET definition. + - `load_balancer_key` - (`string`, optional) a key describing a Load Balancer defined in `load_balancers` property. + + For all properties and their default values see + [module's documentation](../../modules/test_infrastructure#test_vms). + +- `bastions` - (`map`, required) a map containing Azure Bastion definitions. The most basic properties are as + follows: + + - `name` - (`string`, required) an Azure Bastion name. + - `vnet_key` - (`string`, required) a key describing a VNET defined in `vnets` property. This VNET should already have an + existing subnet called `AzureBastionSubnet` (the name is hardcoded by Microsoft). + - `subnet_key` - (`string`, required) a key pointing to a Subnet dedicated to a Bastion deployment. + + For all properties and their default values see + [module's documentation](../../modules/test_infrastructure#bastions). + + +Type: + +```hcl +map(object({ + create_resource_group = optional(bool, true) + resource_group_name = optional(string) + vnets = map(object({ + create_virtual_network = optional(bool, true) + name = string + address_space = optional(list(string)) + dns_servers = optional(list(string)) + vnet_encryption = optional(string) + ddos_protection_plan_id = optional(string) + hub_vnet_key = optional(string) + network_security_groups = optional(map(object({ + name = string + rules = optional(map(object({ + name = string + priority = number + direction = string + access = string + protocol = string + source_port_range = optional(string) + source_port_ranges = optional(list(string)) + destination_port_range = optional(string) + destination_port_ranges = optional(list(string)) + source_address_prefix = optional(string) + source_address_prefixes = optional(list(string)) + destination_address_prefix = optional(string) + destination_address_prefixes = optional(list(string)) + })), {}) + })), {}) + route_tables = optional(map(object({ + name = string + bgp_route_propagation_enabled = optional(bool) + routes = map(object({ + name = string + address_prefix = string + next_hop_type = string + next_hop_ip_address = optional(string) + })) + })), {}) + subnets = optional(map(object({ + create = optional(bool, true) + name = string + address_prefixes = optional(list(string), []) + network_security_group_key = optional(string) + route_table_key = optional(string) + default_outbound_access_enabled = optional(bool) + enable_storage_service_endpoint = optional(bool) + enable_appgw_delegation = optional(bool) + enable_cloudngfw_delegation = optional(bool) + })), {}) + local_peer_config = optional(object({ + allow_virtual_network_access = optional(bool, true) + allow_forwarded_traffic = optional(bool, true) + allow_gateway_transit = optional(bool, false) + use_remote_gateways = optional(bool, false) + }), {}) + remote_peer_config = optional(object({ + allow_virtual_network_access = optional(bool, true) + allow_forwarded_traffic = optional(bool, true) + allow_gateway_transit = optional(bool, false) + use_remote_gateways = optional(bool, false) + }), {}) + })) + load_balancers = optional(map(object({ + name = string + vnet_key = optional(string) + zones = optional(list(string), ["1", "2", "3"]) + backend_name = optional(string) + health_probes = optional(map(object({ + name = string + protocol = string + port = optional(number) + probe_threshold = optional(number) + interval_in_seconds = optional(number) + request_path = optional(string) + }))) + nsg_auto_rules_settings = optional(object({ + nsg_name = optional(string) + nsg_vnet_key = optional(string) + nsg_key = optional(string) + nsg_resource_group_name = optional(string) + source_ips = list(string) + base_priority = optional(number) + })) + frontend_ips = optional(map(object({ + name = string + subnet_key = optional(string) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + public_ip_prefix_key = optional(string) + private_ip_address = optional(string) + gwlb_key = optional(string) + in_rules = optional(map(object({ + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + })), {}) + out_rules = optional(map(object({ + name = string + protocol = string + allocated_outbound_ports = optional(number) + enable_tcp_reset = optional(bool) + idle_timeout_in_minutes = optional(number) + })), {}) + })), {}) + })), {}) + authentication = optional(object({ + username = optional(string, "bitnami") + password = optional(string) + }), {}) + spoke_vms = map(object({ + name = string + interface_name = optional(string) + disk_name = optional(string) + vnet_key = string + subnet_key = string + load_balancer_key = optional(string) + private_ip_address = optional(string) + size = optional(string) + image = optional(object({ + publisher = optional(string) + offer = optional(string) + sku = optional(string) + version = optional(string) + enable_marketplace_plan = optional(bool) + }), {}) + custom_data = optional(string) + })) + bastions = map(object({ + name = string + create_public_ip = optional(bool, true) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + vnet_key = string + subnet_key = string + })) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) \ No newline at end of file