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.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{
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.{
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.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`. 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.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"
}
}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. 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.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"
}
}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.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
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. {"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)` | [| 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. |
"GroupMinSize",
"GroupMaxSize",
"GroupDesiredCapacity",
"GroupInServiceInstances",
"GroupPendingInstances",
"GroupStandbyInstances",
"GroupTerminatingInstances",
"GroupTotalInstances",
"WarmPoolDesiredCapacity",
"WarmPoolWarmedCapacity",
"WarmPoolPendingCapacity",
"WarmPoolTerminatingCapacity",
"WarmPoolTotalCapacity",
"GroupAndWarmPoolDesiredCapacity",
"GroupAndWarmPoolTotalCapacity"
]
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, 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.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.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.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-.\*' \| sortTo 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)` |
[| no | -| [bootstrap\_options](#input\_bootstrap\_options) | Object define bootstrap options used in the init-cfg.txt file.
"config/",
"content/",
"software/",
"license/",
"plugins/"
]
{
"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.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.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.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.subnets = module.subnet\_set.subnetsExample:
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 attributesubnets = module.subnet\_set.subnetsExample:
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 wouldnext\_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`.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`.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.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.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.subnets = module.subnet\_set.subnetsExample:
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.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.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"
...
}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.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.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"
...
}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.ebs\_volumes = [| `list(any)` | `[]` | no | +| [ebs\_volumes](#input\_ebs\_volumes) | List of EBS volumes to create and attach to Panorama.
{
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"
},
]
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.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. 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.
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.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.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.
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-.\*' \| sortTo 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.
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.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.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.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: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.
+
+[](https://github.com/PaloAltoNetworks/terraform-aws-swfw-modules/tree/main/examples/cloudngfw_centralized_design) [](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" : [
+ 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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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
+
+
+
+[](https://github.com/PaloAltoNetworks/terraform-aws-swfw-modules/tree/main/examples/cloudngfw_distributed_design) [](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" : [
+ 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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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{
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.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{
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.{
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.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`. 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.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"
}
}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. 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.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"
}
}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.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
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. {"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)` | [| 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. |
"GroupMinSize",
"GroupMaxSize",
"GroupDesiredCapacity",
"GroupInServiceInstances",
"GroupPendingInstances",
"GroupStandbyInstances",
"GroupTerminatingInstances",
"GroupTotalInstances",
"WarmPoolDesiredCapacity",
"WarmPoolWarmedCapacity",
"WarmPoolPendingCapacity",
"WarmPoolTerminatingCapacity",
"WarmPoolTotalCapacity",
"GroupAndWarmPoolDesiredCapacity",
"GroupAndWarmPoolTotalCapacity"
]
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, 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.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.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.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-.\*' \| sortTo 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)` |
[| no | -| [bootstrap\_options](#input\_bootstrap\_options) | Object define bootstrap options used in the init-cfg.txt file.
"config/",
"content/",
"software/",
"license/",
"plugins/"
]
{
"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.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.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.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.subnets = module.subnet\_set.subnetsExample:
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`.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`.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.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.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.subnets = module.subnet\_set.subnetsExample:
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.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.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"
...
}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.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.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"
...
}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.ebs\_volumes = [| `list(any)` | `[]` | no | +| [ebs\_volumes](#input\_ebs\_volumes) | List of EBS volumes to create and attach to Panorama.
{
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"
},
]
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.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. 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.
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.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.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.
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-.\*' \| sortTo 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.
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.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.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.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: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.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.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.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.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.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.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.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.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.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.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.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 instancesvmseries = {
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.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.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.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.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.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.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 instancesvmseries = {
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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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 instancesvmseries = {
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.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.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.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.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.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.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 instancesvmseries = {
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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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 instancesvmseries = {
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.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.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.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.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 instancesvmseries = {
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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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).
+
+[](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/tree/main/examples/vmseries_transit_vnet_dedicated_vwan) [](https://registry.terraform.io/modules/PaloAltoNetworks/swfw-modules/azurerm/latest/examples/vmseries_transit_vnet_dedicated_vwan)
+
+## Reference Architecture Design
+
+
+
+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.
+
+
+
+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`](