From 3c1e010bdb27690a53ad13e37c8aad5a5ed655f5 Mon Sep 17 00:00:00 2001 From: Slawomir Kaczmarek Date: Thu, 19 Sep 2024 11:54:16 +0200 Subject: [PATCH] feat: Add SCM bootstrap options (#80) Co-authored-by: Slawomir Kaczmarek --- examples/centralized_design/README.md | 2 +- examples/centralized_design/example.tfvars | 25 ++++++++++++++++--- examples/centralized_design/main.tf | 2 +- examples/centralized_design/variables.tf | 23 +++++++++-------- .../centralized_design_autoscale/README.md | 2 +- .../example.tfvars | 20 ++++++++++++++- examples/centralized_design_autoscale/main.tf | 2 +- .../centralized_design_autoscale/variables.tf | 23 +++++++++-------- examples/combined_design/README.md | 2 +- examples/combined_design/example.tfvars | 25 ++++++++++++++++--- examples/combined_design/main.tf | 2 +- examples/combined_design/variables.tf | 23 +++++++++-------- examples/combined_design_autoscale/README.md | 2 +- .../example-natgw-lambda-vpc.tfvars | 19 +++++++++++++- .../example-no-natgw-lambda-no-vpc.tfvars | 19 +++++++++++++- .../combined_design_autoscale/example.tfvars | 19 +++++++++++++- examples/combined_design_autoscale/main.tf | 2 +- .../combined_design_autoscale/variables.tf | 23 +++++++++-------- examples/isolated_design/README.md | 2 +- examples/isolated_design/example.tfvars | 19 +++++++++++++- examples/isolated_design/main.tf | 2 +- examples/isolated_design/variables.tf | 23 +++++++++-------- examples/isolated_design_autoscale/README.md | 2 +- .../isolated_design_autoscale/example.tfvars | 19 +++++++++++++- examples/isolated_design_autoscale/main.tf | 2 +- .../isolated_design_autoscale/variables.tf | 23 +++++++++-------- examples/vmseries_standalone/README.md | 2 +- examples/vmseries_standalone/example.tfvars | 17 ++++++++++++- examples/vmseries_standalone/main.tf | 2 +- examples/vmseries_standalone/variables.tf | 20 ++++++++------- 30 files changed, 270 insertions(+), 98 deletions(-) diff --git a/examples/centralized_design/README.md b/examples/centralized_design/README.md index 38de0ba..c985bf1 100644 --- a/examples/centralized_design/README.md +++ b/examples/centralized_design/README.md @@ -120,7 +120,7 @@ To enable access from the session manager, the Internet connection for a public | [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

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

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

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

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route_tables = {
"from_security_vpc" = {
create = true
name = "from_security"
}
}
attachments = {
security = {
name = "vmseries"
vpc = "security_vpc"
subnet_group = "tgw_attach"
route_table = "from_security_vpc"
propagate_routes_to = "from_spoke_vpc"
}
}
}
|
object({
create = bool
id = string
name = string
asn = string
route_tables = map(object({
create = bool
name = string
}))
attachments = map(object({
name = string
vpc = string
subnet_group = string
route_table = string
propagate_routes_to = string
}))
})
| `null` | no | -| [vmseries](#input\_vmseries) | A map defining VM-Series instances

Following properties are available:
- `instances`: map of VM-Series instances
- `bootstrap_options`: VM-Seriess bootstrap options used to connect to Panorama
- `panos_version`: PAN-OS version used for VM-Series
- `ebs_kms_id`: alias for AWS KMS used for EBS encryption in VM-Series
- `vpc`: key of VPC
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces

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

# Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`
bootstrap_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable"
dhcp-send-hostname = "yes"
dhcp-send-client-id = "yes"
dhcp-accept-server-hostname = "yes"
dhcp-accept-server-domain = "yes"
}

panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here

# Value of `vpc` must match key of objects stored in `vpcs`
vpc = "security_vpc"

# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security_gwlb"

interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
vpc = "security_vpc"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
vpc = "security_vpc"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
vpc = "security_vpc"
subnet_group = "public"
create_public_ip = true
source_dest_check = false
}
}

# Value of `gwlb_endpoint` must match key of objects stored in `gwlb_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

system_services = {
dns_primary = "4.2.2.2" # TODO: update here
dns_secondy = null # TODO: update here
ntp_primary = "pool.ntp.org" # TODO: update here
ntp_secondy = null # TODO: update here
}

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 = string
dgname = string
tplname = string
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = 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 | +| [vmseries](#input\_vmseries) | A map defining VM-Series instances

Following properties are available:
- `instances`: map of VM-Series instances
- `bootstrap_options`: VM-Seriess bootstrap options used to connect to Panorama
- `panos_version`: PAN-OS version used for VM-Series
- `ebs_kms_id`: alias for AWS KMS used for EBS encryption in VM-Series
- `vpc`: key of VPC
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces

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

# Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`
bootstrap_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable"
dhcp-send-hostname = "yes"
dhcp-send-client-id = "yes"
dhcp-accept-server-hostname = "yes"
dhcp-accept-server-domain = "yes"
}

panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here

# Value of `vpc` must match key of objects stored in `vpcs`
vpc = "security_vpc"

# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security_gwlb"

interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
vpc = "security_vpc"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
vpc = "security_vpc"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
vpc = "security_vpc"
subnet_group = "public"
create_public_ip = true
source_dest_check = false
}
}

# Value of `gwlb_endpoint` must match key of objects stored in `gwlb_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

system_services = {
dns_primary = "4.2.2.2" # TODO: update here
dns_secondy = null # TODO: update here
ntp_primary = "pool.ntp.org" # TODO: update here
ntp_secondy = null # TODO: update here
}

application_lb = null
network_lb = null
}
}
|
map(object({
instances = map(object({
az = string
}))

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

panos_version = string
ebs_kms_id = string

vpc = string
gwlb = string

interfaces = map(object({
device_index = number
security_group = string
vpc = string
subnet_group = string
create_public_ip = bool
source_dest_check = bool
}))

subinterfaces = map(map(object({
gwlb_endpoint = string
subinterface = string
})))

system_services = object({
dns_primary = string
dns_secondy = string
ntp_primary = string
ntp_secondy = string
})

application_lb = object({
name = string
subnet_group = string
security_group = string
rules = any
})

network_lb = object({
name = string
subnet_group = string
rules = any
})
}))
| `{}` | no | | [vpcs](#input\_vpcs) | A map defining VPCs with security groups and subnets.

Following properties are available:
- `name`: VPC name
- `cidr`: CIDR for VPC
- `security_groups`: map of security groups
- `subnets`: map of subnets with properties:
- `az`: availability zone
- `subnet_group`: identity of the same purpose subnets group such as management
- `routes`: map of routes with properties:
- `vpc - key of the VPC
- `subnet\_group` - key of the subnet group
- `next\_hop\_key` - must match keys use to create TGW attachment, IGW, GWLB endpoint or other resources
- `next\_hop\_type` - internet_gateway, nat_gateway, transit_gateway_attachment or gwlbe_endpoint

Example:
`
vpcs = {
example_vpc = {
name = "example-spoke-vpc"
cidr = "10.104.0.0/16"
nacls = {
trusted_path_monitoring = {
name = "trusted-path-monitoring"
rules = {
allow_inbound = {
rule_number = 300
egress = false
protocol = "-1"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = null
to_port = null
}
}
}
}
security_groups = {
example_vm = {
name = "example_vm"
rules = {
all_outbound = {
description = "Permit All traffic outbound"
type = "egress", from_port = "0", to_port = "0", protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
}
subnets = {
"10.104.0.0/24" = { az = "eu-central-1a", subnet_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet_group = "vm", nacl = null }
}
routes = {
vm_default = {
vpc = "app1_vpc"
subnet_group = "app1_vm"
to_cidr = "0.0.0.0/0"
next_hop_key = "app1"
next_hop_type = "transit_gateway_attachment"
}
}
}
}
|
map(object({
name = string
cidr = string
nacls = map(object({
name = string
rules = map(object({
rule_number = number
egress = bool
protocol = string
rule_action = string
cidr_block = string
from_port = string
to_port = string
}))
}))
security_groups = any
subnets = map(object({
az = string
subnet_group = string
nacl = string
}))
routes = map(object({
vpc = string
subnet_group = string
to_cidr = string
next_hop_key = string
next_hop_type = string
}))
}))
| `{}` | no | ### Outputs diff --git a/examples/centralized_design/example.tfvars b/examples/centralized_design/example.tfvars index b0983da..3ba4139 100644 --- a/examples/centralized_design/example.tfvars +++ b/examples/centralized_design/example.tfvars @@ -488,20 +488,37 @@ vmseries = { "02" = { az = "eu-west-1b" } } - # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license` + # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`. Delete map if SCM bootstrap required. 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 = "10.255.0.10" # TODO: update here + panorama-server = "" # TODO: update here auth-key = "" # TODO: update here - dgname = "centralized" # TODO: update here - tplname = "centralized-stack" # 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 } + /* Uncomment this section if SCM bootstrap required (PAN-OS version 11.0 or higher) + + bootstrap_options = { + mgmt-interface-swap = "enable" + panorama-server = "cloud" # TODO: update here + dgname = "scm_folder_name" # 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 + plugin-op-commands = "aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable,advance-routing:enable" # TODO: update here + vm-series-auto-registration-pin-id = "1234ab56-1234-12a3-a1bc-a1bc23456de7" # TODO: update here + vm-series-auto-registration-pin-value = "12ab3c456d78901e2f3abc456d78ef9a" # TODO: update here + authcodes = "D1234567" # TODO: update here + } + */ + panos_version = "10.2.9-h1" # TODO: update here ebs_kms_id = "alias/aws/ebs" # TODO: update here diff --git a/examples/centralized_design/main.tf b/examples/centralized_design/main.tf index c702c48..63c8ffb 100644 --- a/examples/centralized_design/main.tf +++ b/examples/centralized_design/main.tf @@ -252,7 +252,7 @@ locals { plugin_op_commands_with_endpoints_mapping = { for i, j in var.vmseries : i => format("%s,%s,%s,%s", j.bootstrap_options["plugin-op-commands"], local.subinterface_gwlb_endpoint_eastwest[i], local.subinterface_gwlb_endpoint_outbound[i], local.subinterface_gwlb_endpoint_inbound[i]) } bootstrap_options_with_endpoints_mapping = { for i, j in var.vmseries : i => [ - for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" + for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" if v != null ] } } diff --git a/examples/centralized_design/variables.tf b/examples/centralized_design/variables.tf index 1486214..bfbcdb7 100644 --- a/examples/centralized_design/variables.tf +++ b/examples/centralized_design/variables.tf @@ -387,16 +387,19 @@ variable "vmseries" { })) bootstrap_options = object({ - mgmt-interface-swap = string - plugin-op-commands = string - panorama-server = string - auth-key = string - dgname = string - tplname = string - dhcp-send-hostname = string - dhcp-send-client-id = string - dhcp-accept-server-hostname = string - dhcp-accept-server-domain = string + mgmt-interface-swap = string + plugin-op-commands = string + panorama-server = string + 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 diff --git a/examples/centralized_design_autoscale/README.md b/examples/centralized_design_autoscale/README.md index 395d1f6..be09d20 100644 --- a/examples/centralized_design_autoscale/README.md +++ b/examples/centralized_design_autoscale/README.md @@ -201,7 +201,7 @@ statistic = "Maximum" | [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

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

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

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

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route_tables = {
"from_security_vpc" = {
create = true
name = "from_security"
}
}
attachments = {
security = {
name = "vmseries"
vpc = "security_vpc"
subnet_group = "tgw_attach"
route_table = "from_security_vpc"
propagate_routes_to = "from_spoke_vpc"
}
}
}
|
object({
create = bool
id = string
name = string
asn = string
route_tables = map(object({
create = bool
name = string
}))
attachments = map(object({
name = string
vpc = string
subnet_group = string
route_table = string
propagate_routes_to = string
}))
})
| `null` | no | -| [vmseries\_asgs](#input\_vmseries\_asgs) | A map defining Autoscaling Groups with VM-Series instances.

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

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

panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here

vpc = "security_vpc"
gwlb = "security_gwlb"

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

interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
subnet_group = "public"
create_public_ip = false
source_dest_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired_cap = 0
min_size = 0
max_size = 4
lambda_execute_pip_install_once = true
}

scaling_plan = {
enabled = true
metric_name = "panSessionActive"
estimated_instance_warmup = 900
target_value = 75
statistic = "Average"
cloudwatch_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch_template_version = "1"

instance_refresh = {
strategy = "Rolling"
preferences = {
checkpoint_delay = 3600
checkpoint_percentages = [50, 100]
instance_warmup = 1200
min_healthy_percentage = 50
skip_matching = false
auto_rollback = false
scale_in_protected_instances = "Ignore"
standby_instances = "Ignore"
}
triggers = []
}

application_lb = null
network_lb = null
}
}
|
map(object({
bootstrap_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = string
dgname = string
tplname = string
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = 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 | +| [vmseries\_asgs](#input\_vmseries\_asgs) | A map defining Autoscaling Groups with VM-Series instances.

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

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

panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here

vpc = "security_vpc"
gwlb = "security_gwlb"

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

interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
subnet_group = "public"
create_public_ip = false
source_dest_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired_cap = 0
min_size = 0
max_size = 4
lambda_execute_pip_install_once = true
}

scaling_plan = {
enabled = true
metric_name = "panSessionActive"
estimated_instance_warmup = 900
target_value = 75
statistic = "Average"
cloudwatch_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch_template_version = "1"

instance_refresh = {
strategy = "Rolling"
preferences = {
checkpoint_delay = 3600
checkpoint_percentages = [50, 100]
instance_warmup = 1200
min_healthy_percentage = 50
skip_matching = false
auto_rollback = false
scale_in_protected_instances = "Ignore"
standby_instances = "Ignore"
}
triggers = []
}

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

panos_version = string
ebs_kms_id = string

vpc = string
gwlb = string

zones = map(any)

interfaces = map(object({
device_index = number
security_group = string
subnet_group = string
create_public_ip = bool
source_dest_check = bool
}))

subinterfaces = map(map(object({
gwlb_endpoint = string
subinterface = string
})))

asg = object({
desired_cap = number
min_size = number
max_size = number
lambda_execute_pip_install_once = bool
})

scaling_plan = object({
enabled = bool
metric_name = string
estimated_instance_warmup = number
target_value = number
statistic = string
cloudwatch_namespace = string
tags = map(string)
})

launch_template_version = string

instance_refresh = object({
strategy = string
preferences = object({
checkpoint_delay = number
checkpoint_percentages = list(number)
instance_warmup = number
min_healthy_percentage = number
skip_matching = bool
auto_rollback = bool
scale_in_protected_instances = string
standby_instances = string
})
triggers = list(string)
})

application_lb = object({
name = string
subnet_group = string
security_group = string
rules = any
})

network_lb = object({
name = string
subnet_group = string
rules = any
})
}))
| `{}` | no | | [vpcs](#input\_vpcs) | A map defining VPCs with security groups and subnets.

Following properties are available:
- `name`: VPC name
- `cidr`: CIDR for VPC
- `security_groups`: map of security groups
- `subnets`: map of subnets with properties:
- `az`: availability zone
- `subnet_group`: identity of the same purpose subnets group such as management
- `routes`: map of routes with properties:
- `vpc - key of the VPC
- `subnet\_group` - key of the subnet group
- `next\_hop\_key` - must match keys use to create TGW attachment, IGW, GWLB endpoint or other resources
- `next\_hop\_type` - internet_gateway, nat_gateway, transit_gateway_attachment or gwlbe_endpoint

Example:
`
vpcs = {
example_vpc = {
name = "example-spoke-vpc"
cidr = "10.104.0.0/16"
nacls = {
trusted_path_monitoring = {
name = "trusted-path-monitoring"
rules = {
allow_inbound = {
rule_number = 300
egress = false
protocol = "-1"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = null
to_port = null
}
}
}
}
security_groups = {
example_vm = {
name = "example_vm"
rules = {
all_outbound = {
description = "Permit All traffic outbound"
type = "egress", from_port = "0", to_port = "0", protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
}
subnets = {
"10.104.0.0/24" = { az = "eu-central-1a", subnet_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet_group = "vm", nacl = null }
}
routes = {
vm_default = {
vpc = "app1_vpc"
subnet_group = "app1_vm"
to_cidr = "0.0.0.0/0"
next_hop_key = "app1"
next_hop_type = "transit_gateway_attachment"
}
}
}
}
|
map(object({
name = string
cidr = string
nacls = map(object({
name = string
rules = map(object({
rule_number = number
egress = bool
protocol = string
rule_action = string
cidr_block = string
from_port = string
to_port = string
}))
}))
security_groups = any
subnets = map(object({
az = string
subnet_group = string
nacl = string
}))
routes = map(object({
vpc = string
subnet_group = string
to_cidr = string
next_hop_key = string
next_hop_type = string
}))
}))
| `{}` | no | ### Outputs diff --git a/examples/centralized_design_autoscale/example.tfvars b/examples/centralized_design_autoscale/example.tfvars index e5ff1c3..47f292d 100644 --- a/examples/centralized_design_autoscale/example.tfvars +++ b/examples/centralized_design_autoscale/example.tfvars @@ -483,7 +483,8 @@ gwlb_endpoints = { ### VM-SERIES vmseries_asgs = { main_asg = { - # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license` + + # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`. Delete map if SCM bootstrap required. 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 @@ -497,6 +498,23 @@ vmseries_asgs = { dhcp-accept-server-domain = "yes" # TODO: update here } + /* Uncomment this section if SCM bootstrap required (PAN-OS version 11.0 or higher) + + bootstrap_options = { + mgmt-interface-swap = "enable" + panorama-server = "cloud" # TODO: update here + dgname = "scm_folder_name" # 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 + plugin-op-commands = "aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable,advance-routing:enable" # TODO: update here + vm-series-auto-registration-pin-id = "1234ab56-1234-12a3-a1bc-a1bc23456de7" # TODO: update here + vm-series-auto-registration-pin-value = "12ab3c456d78901e2f3abc456d78ef9a" # TODO: update here + authcodes = "D1234567" # TODO: update here + } + */ + panos_version = "10.2.9-h1" # TODO: update here ebs_kms_id = "alias/aws/ebs" # TODO: update here diff --git a/examples/centralized_design_autoscale/main.tf b/examples/centralized_design_autoscale/main.tf index 62aa643..8692910 100644 --- a/examples/centralized_design_autoscale/main.tf +++ b/examples/centralized_design_autoscale/main.tf @@ -242,7 +242,7 @@ locals { plugin_op_commands_with_endpoints_mapping = { for i, j in var.vmseries_asgs : i => format("%s,%s,%s,%s", j.bootstrap_options["plugin-op-commands"], local.subinterface_gwlb_endpoint_eastwest[i], local.subinterface_gwlb_endpoint_outbound[i], local.subinterface_gwlb_endpoint_inbound[i]) } bootstrap_options_with_endpoints_mapping = { for i, j in var.vmseries_asgs : i => [ - for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" + for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" if v != null ] } } diff --git a/examples/centralized_design_autoscale/variables.tf b/examples/centralized_design_autoscale/variables.tf index 0f8d94b..e2465b4 100644 --- a/examples/centralized_design_autoscale/variables.tf +++ b/examples/centralized_design_autoscale/variables.tf @@ -417,16 +417,19 @@ variable "vmseries_asgs" { default = {} type = map(object({ bootstrap_options = object({ - mgmt-interface-swap = string - plugin-op-commands = string - panorama-server = string - auth-key = string - dgname = string - tplname = string - dhcp-send-hostname = string - dhcp-send-client-id = string - dhcp-accept-server-hostname = string - dhcp-accept-server-domain = string + mgmt-interface-swap = string + plugin-op-commands = string + panorama-server = string + 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 diff --git a/examples/combined_design/README.md b/examples/combined_design/README.md index a57282c..20660e3 100644 --- a/examples/combined_design/README.md +++ b/examples/combined_design/README.md @@ -155,7 +155,7 @@ If no errors occurred during deployment, configure the VM-Series machines as exp | [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

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

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

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

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route_tables = {
"from_security_vpc" = {
create = true
name = "from_security"
}
}
attachments = {
security = {
name = "vmseries"
vpc = "security_vpc"
subnet_group = "tgw_attach"
route_table = "from_security_vpc"
propagate_routes_to = "from_spoke_vpc"
}
}
}
|
object({
create = bool
id = string
name = string
asn = string
route_tables = map(object({
create = bool
name = string
}))
attachments = map(object({
name = string
vpc = string
subnet_group = string
route_table = string
propagate_routes_to = string
}))
})
| `null` | no | -| [vmseries](#input\_vmseries) | A map defining VM-Series instances
Following properties are available:
- `instances`: map of VM-Series instances
- `bootstrap_options`: VM-Seriess bootstrap options used to connect to Panorama
- `panos_version`: PAN-OS version used for VM-Series
- `ebs_kms_id`: alias for AWS KMS used for EBS encryption in VM-Series
- `vpc`: key of VPC
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces
Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
"02" = { az = "eu-central-1b" }
}
# Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`
bootstrap_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable"
dhcp-send-hostname = "yes"
dhcp-send-client-id = "yes"
dhcp-accept-server-hostname = "yes"
dhcp-accept-server-domain = "yes"
}
panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here
# Value of `vpc` must match key of objects stored in `vpcs`
vpc = "security_vpc"
# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security_gwlb"
interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
vpc = "security_vpc"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
vpc = "security_vpc"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
vpc = "security_vpc"
subnet_group = "public"
create_public_ip = true
source_dest_check = false
}
}
# Value of `gwlb_endpoint` must match key of objects stored in `gwlb_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}
system_services = {
dns_primary = "4.2.2.2" # TODO: update here
dns_secondy = null # TODO: update here
ntp_primary = "pool.ntp.org" # TODO: update here
ntp_secondy = null # TODO: update here
}
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 = string
dgname = string
tplname = string
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = 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 | +| [vmseries](#input\_vmseries) | A map defining VM-Series instances
Following properties are available:
- `instances`: map of VM-Series instances
- `bootstrap_options`: VM-Seriess bootstrap options used to connect to Panorama
- `panos_version`: PAN-OS version used for VM-Series
- `ebs_kms_id`: alias for AWS KMS used for EBS encryption in VM-Series
- `vpc`: key of VPC
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces
Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
"02" = { az = "eu-central-1b" }
}
# Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`
bootstrap_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable"
dhcp-send-hostname = "yes"
dhcp-send-client-id = "yes"
dhcp-accept-server-hostname = "yes"
dhcp-accept-server-domain = "yes"
}
panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here
# Value of `vpc` must match key of objects stored in `vpcs`
vpc = "security_vpc"
# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security_gwlb"
interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
vpc = "security_vpc"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
vpc = "security_vpc"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
vpc = "security_vpc"
subnet_group = "public"
create_public_ip = true
source_dest_check = false
}
}
# Value of `gwlb_endpoint` must match key of objects stored in `gwlb_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}
system_services = {
dns_primary = "4.2.2.2" # TODO: update here
dns_secondy = null # TODO: update here
ntp_primary = "pool.ntp.org" # TODO: update here
ntp_secondy = null # TODO: update here
}
application_lb = null
network_lb = null
}
}
|
map(object({
instances = map(object({
az = string
}))

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

panos_version = string
ebs_kms_id = string

vpc = string
gwlb = string

interfaces = map(object({
device_index = number
security_group = string
vpc = string
subnet_group = string
create_public_ip = bool
source_dest_check = bool
}))

subinterfaces = map(map(object({
gwlb_endpoint = string
subinterface = string
})))

system_services = object({
dns_primary = string
dns_secondy = string
ntp_primary = string
ntp_secondy = string
})

application_lb = object({
name = string
rules = any
})

network_lb = object({
name = string
rules = any
})
}))
| `{}` | no | | [vpcs](#input\_vpcs) | A map defining VPCs with security groups and subnets.

Following properties are available:
- `name`: VPC name
- `cidr`: CIDR for VPC
- `nacls`: map of network ACLs
- `security_groups`: map of security groups
- `subnets`: map of subnets with properties:
- `az`: availability zone
- `subnet_group`: identity of the same purpose subnets group such as management
- `nacl`: key of NACL (can be null)
- `routes`: map of routes with properties:
- `vpc` - VPC key
- `subnet_group` - subnet\_group key
- `next_hop_key` - must match keys use to create TGW attachment, IGW, GWLB endpoint or other resources
- `next_hop_type` - internet\_gateway, nat\_gateway, transit\_gateway\_attachment or gwlbe\_endpoint

Example:
vpcs = {
example_vpc = {
name = "example-spoke-vpc"
cidr = "10.104.0.0/16"
nacls = {
trusted_path_monitoring = {
name = "trusted-path-monitoring"
rules = {
allow_inbound = {
rule_number = 300
egress = false
protocol = "-1"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = null
to_port = null
}
}
}
}
security_groups = {
example_vm = {
name = "example_vm"
rules = {
all_outbound = {
description = "Permit All traffic outbound"
type = "egress", from_port = "0", to_port = "0", protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
}
subnets = {
"10.104.0.0/24" = { az = "eu-central-1a", subnet_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet_group = "vm", nacl = null }
}
routes = {
vm_default = {
vpc = "app1_vpc"
subnet_group = "app1_vm"
to_cidr = "0.0.0.0/0"
next_hop_key = "app1"
next_hop_type = "transit_gateway_attachment"
}
}
}
}
|
map(object({
name = string
cidr = string
nacls = map(object({
name = string
rules = map(object({
rule_number = number
egress = bool
protocol = string
rule_action = string
cidr_block = string
from_port = optional(string)
to_port = optional(string)
}))
}))
security_groups = map(object({
name = string
rules = map(object({
description = string
type = string
from_port = string
to_port = string
protocol = string
cidr_blocks = list(string)
}))
}))
subnets = map(object({
az = string
subnet_group = string
nacl = optional(string)
create_subnet = optional(bool, true)
create_route_table = optional(bool, true)
existing_route_table_id = optional(string)
associate_route_table = optional(bool, true)
route_table_name = optional(string)
local_tags = optional(map(string), {})
}))
routes = map(object({
vpc = string
subnet_group = string
to_cidr = string
next_hop_key = string
next_hop_type = string
}))
}))
| `{}` | no | ### Outputs diff --git a/examples/combined_design/example.tfvars b/examples/combined_design/example.tfvars index f174373..2265f32 100644 --- a/examples/combined_design/example.tfvars +++ b/examples/combined_design/example.tfvars @@ -475,20 +475,37 @@ vmseries = { "02" = { az = "eu-west-1b" } } - # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license` + # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`. Delete map if SCM bootstrap required. 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 = "10.255.0.10" # TODO: update here + panorama-server = "" # TODO: update here auth-key = "" # TODO: update here - dgname = "combined" # TODO: update here - tplname = "combined-stack" # 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 } + /* Uncomment this section if SCM bootstrap required (PAN-OS version 11.0 or higher) + + bootstrap_options = { + mgmt-interface-swap = "enable" + panorama-server = "cloud" # TODO: update here + dgname = "scm_folder_name" # 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 + plugin-op-commands = "aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable,advance-routing:enable" # TODO: update here + vm-series-auto-registration-pin-id = "1234ab56-1234-12a3-a1bc-a1bc23456de7" # TODO: update here + vm-series-auto-registration-pin-value = "12ab3c456d78901e2f3abc456d78ef9a" # TODO: update here + authcodes = "D1234567" # TODO: update here + } + */ + panos_version = "10.2.9-h1" # TODO: update here ebs_kms_id = "alias/aws/ebs" # TODO: update here diff --git a/examples/combined_design/main.tf b/examples/combined_design/main.tf index 211e45b..68a4e59 100644 --- a/examples/combined_design/main.tf +++ b/examples/combined_design/main.tf @@ -252,7 +252,7 @@ locals { plugin_op_commands_with_endpoints_mapping = { for i, j in var.vmseries : i => format("%s,%s,%s,%s", j.bootstrap_options["plugin-op-commands"], local.subinterface_gwlb_endpoint_eastwest[i], local.subinterface_gwlb_endpoint_outbound[i], local.subinterface_gwlb_endpoint_inbound[i]) } bootstrap_options_with_endpoints_mapping = { for i, j in var.vmseries : i => [ - for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" + for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" if v != null ] } } diff --git a/examples/combined_design/variables.tf b/examples/combined_design/variables.tf index 6113021..f19d949 100644 --- a/examples/combined_design/variables.tf +++ b/examples/combined_design/variables.tf @@ -419,16 +419,19 @@ variable "vmseries" { })) bootstrap_options = object({ - mgmt-interface-swap = string - plugin-op-commands = string - panorama-server = string - auth-key = string - dgname = string - tplname = string - dhcp-send-hostname = string - dhcp-send-client-id = string - dhcp-accept-server-hostname = string - dhcp-accept-server-domain = string + mgmt-interface-swap = string + plugin-op-commands = string + panorama-server = string + 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 diff --git a/examples/combined_design_autoscale/README.md b/examples/combined_design_autoscale/README.md index d860919..7a941f1 100644 --- a/examples/combined_design_autoscale/README.md +++ b/examples/combined_design_autoscale/README.md @@ -273,7 +273,7 @@ To enable access from the session manager, the Internet connection for a public | [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

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

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

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

Example:
tgw = {
create = true
id = null
name = "tgw"
asn = "64512"
route_tables = {
"from_security_vpc" = {
create = true
name = "from_security"
}
}
attachments = {
security = {
name = "vmseries"
vpc = "security_vpc"
subnet_group = "tgw_attach"
route_table = "from_security_vpc"
propagate_routes_to = "from_spoke_vpc"
}
}
}
|
object({
create = bool
id = string
name = string
asn = string
route_tables = map(object({
create = bool
name = string
}))
attachments = map(object({
name = string
vpc = string
subnet_group = string
route_table = string
propagate_routes_to = string
}))
})
| `null` | no | -| [vmseries\_asgs](#input\_vmseries\_asgs) | A map defining Autoscaling Groups with VM-Series instances.

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

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

panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here

vpc = "security_vpc"
gwlb = "security_gwlb"

interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
subnet_group = "public"
create_public_ip = false
source_dest_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired_cap = 0
min_size = 0
max_size = 4
lambda_execute_pip_install_once = true
}

scaling_plan = {
enabled = true
metric_name = "panSessionActive"
estimated_instance_warmup = 900
target_value = 75
statistic = "Average"
cloudwatch_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch_template_version = "1"

instance_refresh = {
strategy = "Rolling"
preferences = {
checkpoint_delay = 3600
checkpoint_percentages = [50, 100]
instance_warmup = 1200
min_healthy_percentage = 50
skip_matching = false
auto_rollback = false
scale_in_protected_instances = "Ignore"
standby_instances = "Ignore"
}
triggers = []
}

delicense = {
enabled = true
ssm_param_name = "example_param_store_delicense" # TODO: update here
}
}
}
|
map(object({
bootstrap_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = string
dgname = string
tplname = string
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = 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 | +| [vmseries\_asgs](#input\_vmseries\_asgs) | A map defining Autoscaling Groups with VM-Series instances.

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

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

panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here

vpc = "security_vpc"
gwlb = "security_gwlb"

interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
subnet_group = "public"
create_public_ip = false
source_dest_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired_cap = 0
min_size = 0
max_size = 4
lambda_execute_pip_install_once = true
}

scaling_plan = {
enabled = true
metric_name = "panSessionActive"
estimated_instance_warmup = 900
target_value = 75
statistic = "Average"
cloudwatch_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch_template_version = "1"

instance_refresh = {
strategy = "Rolling"
preferences = {
checkpoint_delay = 3600
checkpoint_percentages = [50, 100]
instance_warmup = 1200
min_healthy_percentage = 50
skip_matching = false
auto_rollback = false
scale_in_protected_instances = "Ignore"
standby_instances = "Ignore"
}
triggers = []
}

delicense = {
enabled = true
ssm_param_name = "example_param_store_delicense" # TODO: update here
}
}
}
|
map(object({
bootstrap_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = optional(string)
dgname = string
tplname = optional(string)
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = string
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos_version = string
ebs_kms_id = string

vpc = string
gwlb = string

zones = map(any)

interfaces = map(object({
device_index = number
security_group = string
subnet_group = string
create_public_ip = bool
source_dest_check = bool
}))

subinterfaces = map(map(object({
gwlb_endpoint = string
subinterface = string
})))

asg = object({
desired_cap = number
min_size = number
max_size = number
lambda_execute_pip_install_once = bool
})

scaling_plan = object({
enabled = bool
metric_name = string
estimated_instance_warmup = number
target_value = number
statistic = string
cloudwatch_namespace = string
tags = map(string)
})

launch_template_version = string

instance_refresh = object({
strategy = string
preferences = object({
checkpoint_delay = number
checkpoint_percentages = list(number)
instance_warmup = number
min_healthy_percentage = number
skip_matching = bool
auto_rollback = bool
scale_in_protected_instances = string
standby_instances = string
})
triggers = list(string)
})

delicense = object({
enabled = bool
ssm_param_name = string
})
}))
| `{}` | no | | [vpcs](#input\_vpcs) | A map defining VPCs with security groups and subnets.

Following properties are available:
- `name`: VPC name
- `cidr`: CIDR for VPC
- `nacls`: map of network ACLs
- `security_groups`: map of security groups
- `subnets`: map of subnets with properties:
- `az`: availability zone
- `subnet_group`: identity of the same purpose subnets group such as management
- `nacl`: key of NACL (can be null)
- `routes`: map of routes with properties:
- `vpc` - VPC key
- `subnet_group` - subnet\_group key
- `next_hop_key` - must match keys use to create TGW attachment, IGW, GWLB endpoint or other resources
- `next_hop_type` - internet\_gateway, nat\_gateway, transit\_gateway\_attachment or gwlbe\_endpoint

Example:
vpcs = {
example_vpc = {
name = "example-spoke-vpc"
cidr = "10.104.0.0/16"
nacls = {
trusted_path_monitoring = {
name = "trusted-path-monitoring"
rules = {
allow_inbound = {
rule_number = 300
egress = false
protocol = "-1"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = null
to_port = null
}
}
}
}
security_groups = {
example_vm = {
name = "example_vm"
rules = {
all_outbound = {
description = "Permit All traffic outbound"
type = "egress", from_port = "0", to_port = "0", protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
}
subnets = {
"10.104.0.0/24" = { az = "eu-central-1a", subnet_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet_group = "vm", nacl = null }
}
routes = {
vm_default = {
vpc = "app1_vpc"
subnet_group = "app1_vm"
to_cidr = "0.0.0.0/0"
next_hop_key = "app1"
next_hop_type = "transit_gateway_attachment"
}
}
}
}
|
map(object({
name = string
cidr = string
nacls = map(object({
name = string
rules = map(object({
rule_number = number
egress = bool
protocol = string
rule_action = string
cidr_block = string
from_port = optional(string)
to_port = optional(string)
}))
}))
security_groups = map(object({
name = string
rules = map(object({
description = string
type = string
from_port = string
to_port = string
protocol = string
cidr_blocks = list(string)
}))
}))
subnets = map(object({
az = string
subnet_group = string
nacl = optional(string)
create_subnet = optional(bool, true)
create_route_table = optional(bool, true)
existing_route_table_id = optional(string)
associate_route_table = optional(bool, true)
route_table_name = optional(string)
local_tags = optional(map(string), {})
}))
routes = map(object({
vpc = string
subnet_group = string
to_cidr = string
next_hop_key = string
next_hop_type = string
}))
}))
| `{}` | no | ### Outputs diff --git a/examples/combined_design_autoscale/example-natgw-lambda-vpc.tfvars b/examples/combined_design_autoscale/example-natgw-lambda-vpc.tfvars index a04b0ff..59225d9 100644 --- a/examples/combined_design_autoscale/example-natgw-lambda-vpc.tfvars +++ b/examples/combined_design_autoscale/example-natgw-lambda-vpc.tfvars @@ -490,7 +490,7 @@ gwlb_endpoints = { ### VM-SERIES vmseries_asgs = { main_asg = { - # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license` + # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`. Delete map if SCM bootstrap required. 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 @@ -504,6 +504,23 @@ vmseries_asgs = { dhcp-accept-server-domain = "yes" # TODO: update here } + /* Uncomment this section if SCM bootstrap required (PAN-OS version 11.0 or higher) + + bootstrap_options = { + mgmt-interface-swap = "enable" + panorama-server = "cloud" # TODO: update here + dgname = "scm_folder_name" # 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 + plugin-op-commands = "aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable,advance-routing:enable" # TODO: update here + vm-series-auto-registration-pin-id = "1234ab56-1234-12a3-a1bc-a1bc23456de7" # TODO: update here + vm-series-auto-registration-pin-value = "12ab3c456d78901e2f3abc456d78ef9a" # TODO: update here + authcodes = "D1234567" # TODO: update here + } + */ + panos_version = "10.2.9-h1" # TODO: update here ebs_kms_id = "alias/aws/ebs" # TODO: update here diff --git a/examples/combined_design_autoscale/example-no-natgw-lambda-no-vpc.tfvars b/examples/combined_design_autoscale/example-no-natgw-lambda-no-vpc.tfvars index 71b99fd..1336ca8 100644 --- a/examples/combined_design_autoscale/example-no-natgw-lambda-no-vpc.tfvars +++ b/examples/combined_design_autoscale/example-no-natgw-lambda-no-vpc.tfvars @@ -430,7 +430,7 @@ gwlb_endpoints = { ### VM-SERIES vmseries_asgs = { main_asg = { - # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license` + # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`. Delete map if SCM bootstrap required. 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 @@ -444,6 +444,23 @@ vmseries_asgs = { dhcp-accept-server-domain = "yes" # TODO: update here } + /* Uncomment this section if SCM bootstrap required (PAN-OS version 11.0 or higher) + + bootstrap_options = { + mgmt-interface-swap = "enable" + panorama-server = "cloud" # TODO: update here + dgname = "scm_folder_name" # 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 + plugin-op-commands = "aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable,advance-routing:enable" # TODO: update here + vm-series-auto-registration-pin-id = "1234ab56-1234-12a3-a1bc-a1bc23456de7" # TODO: update here + vm-series-auto-registration-pin-value = "12ab3c456d78901e2f3abc456d78ef9a" # TODO: update here + authcodes = "D1234567" # TODO: update here + } + */ + panos_version = "10.2.9-h1" # TODO: update here ebs_kms_id = "alias/aws/ebs" # TODO: update here diff --git a/examples/combined_design_autoscale/example.tfvars b/examples/combined_design_autoscale/example.tfvars index 51ddf10..f0aaa0d 100644 --- a/examples/combined_design_autoscale/example.tfvars +++ b/examples/combined_design_autoscale/example.tfvars @@ -430,7 +430,7 @@ gwlb_endpoints = { ### VM-SERIES vmseries_asgs = { main_asg = { - # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license` + # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`. Delete map if SCM bootstrap required. 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 @@ -444,6 +444,23 @@ vmseries_asgs = { dhcp-accept-server-domain = "yes" # TODO: update here } + /* Uncomment this section if SCM bootstrap required (PAN-OS version 11.0 or higher) + + bootstrap_options = { + mgmt-interface-swap = "enable" + panorama-server = "cloud" # TODO: update here + dgname = "scm_folder_name" # 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 + plugin-op-commands = "aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable,advance-routing:enable" # TODO: update here + vm-series-auto-registration-pin-id = "1234ab56-1234-12a3-a1bc-a1bc23456de7" # TODO: update here + vm-series-auto-registration-pin-value = "12ab3c456d78901e2f3abc456d78ef9a" # TODO: update here + authcodes = "D1234567" # TODO: update here + } + */ + panos_version = "10.2.9-h1" # TODO: update here ebs_kms_id = "alias/aws/ebs" # TODO: update here diff --git a/examples/combined_design_autoscale/main.tf b/examples/combined_design_autoscale/main.tf index 44b921e..0b7071c 100644 --- a/examples/combined_design_autoscale/main.tf +++ b/examples/combined_design_autoscale/main.tf @@ -242,7 +242,7 @@ locals { plugin_op_commands_with_endpoints_mapping = { for i, j in var.vmseries_asgs : i => format("%s,%s,%s,%s", j.bootstrap_options["plugin-op-commands"], local.subinterface_gwlb_endpoint_eastwest[i], local.subinterface_gwlb_endpoint_outbound[i], local.subinterface_gwlb_endpoint_inbound[i]) } bootstrap_options_with_endpoints_mapping = { for i, j in var.vmseries_asgs : i => [ - for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" + for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" if v != null ] } } diff --git a/examples/combined_design_autoscale/variables.tf b/examples/combined_design_autoscale/variables.tf index d71df2d..182f0f3 100644 --- a/examples/combined_design_autoscale/variables.tf +++ b/examples/combined_design_autoscale/variables.tf @@ -432,16 +432,19 @@ variable "vmseries_asgs" { default = {} type = map(object({ bootstrap_options = object({ - mgmt-interface-swap = string - plugin-op-commands = string - panorama-server = string - auth-key = string - dgname = string - tplname = string - dhcp-send-hostname = string - dhcp-send-client-id = string - dhcp-accept-server-hostname = string - dhcp-accept-server-domain = string + mgmt-interface-swap = string + plugin-op-commands = string + panorama-server = string + 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 diff --git a/examples/isolated_design/README.md b/examples/isolated_design/README.md index ed163e1..38fc23a 100644 --- a/examples/isolated_design/README.md +++ b/examples/isolated_design/README.md @@ -120,7 +120,7 @@ To enable access from the session manager, the Internet connection for a public | [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

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

Example:
spoke_lbs = {
"app1-nlb" = {
vpc = "app1_vpc"
subnet_group = "app1_lb"
vms = ["app1_vm01", "app1_vm02"]
}
}
|
map(object({
vpc = string
subnet_group = string
vms = list(string)
}))
| `{}` | no | | [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

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

Example:
spoke_vms = {
"app1_vm01" = {
az = "eu-central-1a"
vpc = "app1_vpc"
subnet_group = "app1_vm"
security_group = "app1_vm"
type = "t2.micro"
}
}
|
map(object({
az = string
vpc = string
subnet_group = string
security_group = string
type = string
}))
| `{}` | no | | [ssh\_key\_name](#input\_ssh\_key\_name) | Name of the SSH key pair existing in AWS key pairs and used to authenticate to VM-Series or test boxes | `string` | n/a | yes | -| [vmseries](#input\_vmseries) | A map defining VM-Series instances
Following properties are available:
- `instances`: map of VM-Series instances
- `bootstrap_options`: VM-Seriess bootstrap options used to connect to Panorama
- `panos_version`: PAN-OS version used for VM-Series
- `ebs_kms_id`: alias for AWS KMS used for EBS encryption in VM-Series
- `vpc`: key of VPC
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces
Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
"02" = { az = "eu-central-1b" }
}
# Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`
bootstrap_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable"
dhcp-send-hostname = "yes"
dhcp-send-client-id = "yes"
dhcp-accept-server-hostname = "yes"
dhcp-accept-server-domain = "yes"
}
panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here
# Value of `vpc` must match key of objects stored in `vpcs`
vpc = "security_vpc"
# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security_gwlb"
interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
vpc = "security_vpc"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
vpc = "security_vpc"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
vpc = "security_vpc"
subnet_group = "public"
create_public_ip = true
source_dest_check = false
}
}
# Value of `gwlb_endpoint` must match key of objects stored in `gwlb_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}
system_services = {
dns_primary = "4.2.2.2" # TODO: update here
dns_secondy = null # TODO: update here
ntp_primary = "pool.ntp.org" # TODO: update here
ntp_secondy = null # TODO: update here
}
application_lb = null
network_lb = null
}
}
|
map(object({
instances = map(object({
az = string
}))

bootstrap_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = string
dgname = string
tplname = string
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = 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 | +| [vmseries](#input\_vmseries) | A map defining VM-Series instances
Following properties are available:
- `instances`: map of VM-Series instances
- `bootstrap_options`: VM-Seriess bootstrap options used to connect to Panorama
- `panos_version`: PAN-OS version used for VM-Series
- `ebs_kms_id`: alias for AWS KMS used for EBS encryption in VM-Series
- `vpc`: key of VPC
- `gwlb`: key of GWLB
- `subinterfaces`: configuration of network subinterfaces used to map with GWLB endpoints
- `system_services`: map of system services
- `application_lb`: ALB placed in front of the Firewalls' public interfaces
- `network_lb`: NLB placed in front of the Firewalls' public interfaces
Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
"02" = { az = "eu-central-1b" }
}
# Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`
bootstrap_options = {
mgmt-interface-swap = "enable"
plugin-op-commands = "panorama-licensing-mode-on,aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable"
dhcp-send-hostname = "yes"
dhcp-send-client-id = "yes"
dhcp-accept-server-hostname = "yes"
dhcp-accept-server-domain = "yes"
}
panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here
# Value of `vpc` must match key of objects stored in `vpcs`
vpc = "security_vpc"
# Value of `gwlb` must match key of objects stored in `gwlbs`
gwlb = "security_gwlb"
interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
vpc = "security_vpc"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
vpc = "security_vpc"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
vpc = "security_vpc"
subnet_group = "public"
create_public_ip = true
source_dest_check = false
}
}
# Value of `gwlb_endpoint` must match key of objects stored in `gwlb_endpoints`
subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}
system_services = {
dns_primary = "4.2.2.2" # TODO: update here
dns_secondy = null # TODO: update here
ntp_primary = "pool.ntp.org" # TODO: update here
ntp_secondy = null # TODO: update here
}
application_lb = null
network_lb = null
}
}
|
map(object({
instances = map(object({
az = string
}))

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

panos_version = string
ebs_kms_id = string

vpc = string
gwlb = string

interfaces = map(object({
device_index = number
security_group = string
vpc = string
subnet_group = string
create_public_ip = bool
source_dest_check = bool
}))

subinterfaces = map(map(object({
gwlb_endpoint = string
subinterface = string
})))

system_services = object({
dns_primary = string
dns_secondy = string
ntp_primary = string
ntp_secondy = string
})

application_lb = object({
name = string
rules = any
})

network_lb = object({
name = string
rules = any
})
}))
| `{}` | no | | [vpcs](#input\_vpcs) | A map defining VPCs with security groups and subnets.

Following properties are available:
- `name`: VPC name
- `cidr`: CIDR for VPC
- `nacls`: map of network ACLs
- `security_groups`: map of security groups
- `subnets`: map of subnets with properties:
- `az`: availability zone
- `subnet_group`: identity of the same purpose subnets group such as management
- `nacl`: key of NACL (can be null)
- `routes`: map of routes with properties:
- `vpc` - key of VPC
- `subnet_group` - key of subnet\_group
- `next_hop_key` - must match keys use to create TGW attachment, IGW, GWLB endpoint or other resources
- `next_hop_type` - internet\_gateway, nat\_gateway, transit\_gateway\_attachment or gwlbe\_endpoint

Example:
vpcs = {
example_vpc = {
name = "example-spoke-vpc"
cidr = "10.104.0.0/16"
nacls = {
trusted_path_monitoring = {
name = "trusted-path-monitoring"
rules = {
allow_inbound = {
rule_number = 300
egress = false
protocol = "-1"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = null
to_port = null
}
}
}
}
security_groups = {
example_vm = {
name = "example_vm"
rules = {
all_outbound = {
description = "Permit All traffic outbound"
type = "egress", from_port = "0", to_port = "0", protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
}
subnets = {
"10.104.0.0/24" = { az = "eu-central-1a", subnet_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet_group = "vm", nacl = null }
}
routes = {
vm_default = {
vpc = "app1_vpc"
subnet_group = "app1_vm"
to_cidr = "0.0.0.0/0"
next_hop_key = "app1"
next_hop_type = "transit_gateway_attachment"
}
}
}
}
|
map(object({
name = string
cidr = string
nacls = map(object({
name = string
rules = map(object({
rule_number = number
egress = bool
protocol = string
rule_action = string
cidr_block = string
from_port = string
to_port = string
}))
}))
security_groups = any
subnets = map(object({
az = string
subnet_group = string
nacl = string
}))
routes = map(object({
vpc = string
subnet_group = string
to_cidr = string
next_hop_key = string
next_hop_type = string
}))
}))
| `{}` | no | ### Outputs diff --git a/examples/isolated_design/example.tfvars b/examples/isolated_design/example.tfvars index ae7ce30..9bfff81 100644 --- a/examples/isolated_design/example.tfvars +++ b/examples/isolated_design/example.tfvars @@ -382,7 +382,7 @@ vmseries = { "02" = { az = "eu-west-1b" } } - # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license` + # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`. Delete map if SCM bootstrap required. 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 @@ -396,6 +396,23 @@ vmseries = { dhcp-accept-server-domain = "yes" # TODO: update here } + /* Uncomment this section if SCM bootstrap required (PAN-OS version 11.0 or higher) + + bootstrap_options = { + mgmt-interface-swap = "enable" + panorama-server = "cloud" # TODO: update here + dgname = "scm_folder_name" # 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 + plugin-op-commands = "aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable,advance-routing:enable" # TODO: update here + vm-series-auto-registration-pin-id = "1234ab56-1234-12a3-a1bc-a1bc23456de7" # TODO: update here + vm-series-auto-registration-pin-value = "12ab3c456d78901e2f3abc456d78ef9a" # TODO: update here + authcodes = "D1234567" # TODO: update here + } + */ + panos_version = "10.2.9-h1" # TODO: update here ebs_kms_id = "alias/aws/ebs" # TODO: update here diff --git a/examples/isolated_design/main.tf b/examples/isolated_design/main.tf index bb2a7e6..42d0423 100644 --- a/examples/isolated_design/main.tf +++ b/examples/isolated_design/main.tf @@ -214,7 +214,7 @@ locals { plugin_op_commands_with_endpoints_mapping = { for i, j in var.vmseries : i => format("%s,%s,%s,%s", j.bootstrap_options["plugin-op-commands"], local.subinterface_gwlb_endpoint_eastwest[i], local.subinterface_gwlb_endpoint_outbound[i], local.subinterface_gwlb_endpoint_inbound[i]) } bootstrap_options_with_endpoints_mapping = { for i, j in var.vmseries : i => [ - for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" + for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" if v != null ] } } diff --git a/examples/isolated_design/variables.tf b/examples/isolated_design/variables.tf index e9660cd..b3fd010 100644 --- a/examples/isolated_design/variables.tf +++ b/examples/isolated_design/variables.tf @@ -320,16 +320,19 @@ variable "vmseries" { })) bootstrap_options = object({ - mgmt-interface-swap = string - plugin-op-commands = string - panorama-server = string - auth-key = string - dgname = string - tplname = string - dhcp-send-hostname = string - dhcp-send-client-id = string - dhcp-accept-server-hostname = string - dhcp-accept-server-domain = string + mgmt-interface-swap = string + plugin-op-commands = string + panorama-server = string + 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 diff --git a/examples/isolated_design_autoscale/README.md b/examples/isolated_design_autoscale/README.md index dac5c75..b8b3a97 100644 --- a/examples/isolated_design_autoscale/README.md +++ b/examples/isolated_design_autoscale/README.md @@ -227,7 +227,7 @@ statistic = "Maximum" | [spoke\_nlbs](#input\_spoke\_nlbs) | A map defining Network Load Balancers deployed in spoke VPCs.

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

Example:
spoke_lbs = {
"app1-nlb" = {
vpc = "app1_vpc
subnet_group = "app1_lb"
vms = ["app1_vm01", "app1_vm02"]
}
}
|
map(object({
vpc = string
subnet_group = string
vms = list(string)
}))
| `{}` | no | | [spoke\_vms](#input\_spoke\_vms) | A map defining VMs in spoke VPCs.

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

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

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

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

panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here

vpc = "security_vpc"
gwlb = "security_gwlb"

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

interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
subnet_group = "public"
create_public_ip = false
source_dest_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired_cap = 0
min_size = 0
max_size = 4
lambda_execute_pip_install_once = true
}

scaling_plan = {
enabled = true
metric_name = "panSessionActive"
estimated_instance_warmup = 900
target_value = 75
statistic = "Average"
cloudwatch_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch_template_version = "1"

instance_refresh = {
strategy = "Rolling"
preferences = {
checkpoint_delay = 3600
checkpoint_percentages = [50, 100]
instance_warmup = 1200
min_healthy_percentage = 50
skip_matching = false
auto_rollback = false
scale_in_protected_instances = "Ignore"
standby_instances = "Ignore"
}
triggers = []
}
}
}
|
map(object({
bootstrap_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = string
dgname = string
tplname = string
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = 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 | +| [vmseries\_asgs](#input\_vmseries\_asgs) | A map defining Autoscaling Groups with VM-Series instances.

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

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

panos_version = "10.2.3" # TODO: update here
ebs_kms_id = "alias/aws/ebs" # TODO: update here

vpc = "security_vpc"
gwlb = "security_gwlb"

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

interfaces = {
private = {
device_index = 0
security_group = "vmseries_private"
subnet_group = "private"
create_public_ip = false
source_dest_check = false
}
mgmt = {
device_index = 1
security_group = "vmseries_mgmt"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
}
public = {
device_index = 2
security_group = "vmseries_public"
subnet_group = "public"
create_public_ip = false
source_dest_check = false
}
}

subinterfaces = {
inbound = {
app1 = {
gwlb_endpoint = "app1_inbound"
subinterface = "ethernet1/1.11"
}
app2 = {
gwlb_endpoint = "app2_inbound"
subinterface = "ethernet1/1.12"
}
}
outbound = {
only_1_outbound = {
gwlb_endpoint = "security_gwlb_outbound"
subinterface = "ethernet1/1.20"
}
}
eastwest = {
only_1_eastwest = {
gwlb_endpoint = "security_gwlb_eastwest"
subinterface = "ethernet1/1.30"
}
}
}

asg = {
desired_cap = 0
min_size = 0
max_size = 4
lambda_execute_pip_install_once = true
}

scaling_plan = {
enabled = true
metric_name = "panSessionActive"
estimated_instance_warmup = 900
target_value = 75
statistic = "Average"
cloudwatch_namespace = "asg-vmseries"
tags = {
ManagedBy = "terraform"
}
}

launch_template_version = "1"

instance_refresh = {
strategy = "Rolling"
preferences = {
checkpoint_delay = 3600
checkpoint_percentages = [50, 100]
instance_warmup = 1200
min_healthy_percentage = 50
skip_matching = false
auto_rollback = false
scale_in_protected_instances = "Ignore"
standby_instances = "Ignore"
}
triggers = []
}
}
}
|
map(object({
bootstrap_options = object({
mgmt-interface-swap = string
plugin-op-commands = string
panorama-server = string
auth-key = optional(string)
dgname = string
tplname = optional(string)
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = string
authcodes = optional(string)
vm-series-auto-registration-pin-id = optional(string)
vm-series-auto-registration-pin-value = optional(string)
})

panos_version = string
ebs_kms_id = string

vpc = string
gwlb = string

zones = map(any)

interfaces = map(object({
device_index = number
security_group = string
subnet_group = string
create_public_ip = bool
source_dest_check = bool
}))

subinterfaces = map(map(object({
gwlb_endpoint = string
subinterface = string
})))

asg = object({
desired_cap = number
min_size = number
max_size = number
lambda_execute_pip_install_once = bool
})

scaling_plan = object({
enabled = bool
metric_name = string
estimated_instance_warmup = number
target_value = number
statistic = string
cloudwatch_namespace = string
tags = map(string)
})

launch_template_version = string

instance_refresh = object({
strategy = string
preferences = object({
checkpoint_delay = number
checkpoint_percentages = list(number)
instance_warmup = number
min_healthy_percentage = number
skip_matching = bool
auto_rollback = bool
scale_in_protected_instances = string
standby_instances = string
})
triggers = list(string)
})
}))
| `{}` | no | | [vpcs](#input\_vpcs) | A map defining VPCs with security groups and subnets.

Following properties are available:
- `name`: VPC name
- `cidr`: CIDR for VPC
- `nacls`: map of network ACLs
- `security_groups`: map of security groups
- `subnets`: map of subnets with properties:
- `az`: availability zone
- `subnet_group`: identity of the same purpose subnets group such as management
- `nacl`: key of NACL (can be null)
- `routes`: map of routes with properties:
- `vpc`: key of VPC
- `subnet_group`: key of subnet\_group
- `next_hop_key`: must match keys use to create TGW attachment, IGW, GWLB endpoint or other resources
- `next_hop_type`: internet\_gateway, nat\_gateway, transit\_gateway\_attachment or gwlbe\_endpoint

Example:
vpcs = {
example_vpc = {
name = "example-spoke-vpc"
cidr = "10.104.0.0/16"
nacls = {
trusted_path_monitoring = {
name = "trusted-path-monitoring"
rules = {
allow_inbound = {
rule_number = 300
egress = false
protocol = "-1"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = null
to_port = null
}
}
}
}
security_groups = {
example_vm = {
name = "example_vm"
rules = {
all_outbound = {
description = "Permit All traffic outbound"
type = "egress", from_port = "0", to_port = "0", protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
}
subnets = {
"10.104.0.0/24" = { az = "eu-central-1a", subnet_group = "vm", nacl = null }
"10.104.128.0/24" = { az = "eu-central-1b", subnet_group = "vm", nacl = null }
}
routes = {
vm_default = {
vpc = "app1_vpc"
subnet_group = "app1_vm"
to_cidr = "0.0.0.0/0"
next_hop_key = "app1"
next_hop_type = "transit_gateway_attachment"
}
}
}
}
|
map(object({
name = string
cidr = string
nacls = map(object({
name = string
rules = map(object({
rule_number = number
egress = bool
protocol = string
rule_action = string
cidr_block = string
from_port = string
to_port = string
}))
}))
security_groups = any
subnets = map(object({
az = string
subnet_group = string
nacl = string
}))
routes = map(object({
vpc = string
subnet_group = string
to_cidr = string
next_hop_key = string
next_hop_type = string
}))
}))
| `{}` | no | ### Outputs diff --git a/examples/isolated_design_autoscale/example.tfvars b/examples/isolated_design_autoscale/example.tfvars index 7834f02..42c9073 100644 --- a/examples/isolated_design_autoscale/example.tfvars +++ b/examples/isolated_design_autoscale/example.tfvars @@ -377,7 +377,7 @@ gwlb_endpoints = { ### VM-SERIES vmseries_asgs = { main_asg = { - # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license` + # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`. Delete map if SCM bootstrap required. 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 @@ -391,6 +391,23 @@ vmseries_asgs = { dhcp-accept-server-domain = "yes" # TODO: update here } + /* Uncomment this section if SCM bootstrap required (PAN-OS version 11.0 or higher) + + bootstrap_options = { + mgmt-interface-swap = "enable" + panorama-server = "cloud" # TODO: update here + dgname = "scm_folder_name" # 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 + plugin-op-commands = "aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable,advance-routing:enable" # TODO: update here + vm-series-auto-registration-pin-id = "1234ab56-1234-12a3-a1bc-a1bc23456de7" # TODO: update here + vm-series-auto-registration-pin-value = "12ab3c456d78901e2f3abc456d78ef9a" # TODO: update here + authcodes = "D1234567" # TODO: update here + } + */ + panos_version = "10.2.9-h1" # TODO: update here ebs_kms_id = "alias/aws/ebs" # TODO: update here diff --git a/examples/isolated_design_autoscale/main.tf b/examples/isolated_design_autoscale/main.tf index 03af041..6eb22c7 100644 --- a/examples/isolated_design_autoscale/main.tf +++ b/examples/isolated_design_autoscale/main.tf @@ -204,7 +204,7 @@ locals { plugin_op_commands_with_endpoints_mapping = { for i, j in var.vmseries_asgs : i => format("%s,%s,%s,%s", j.bootstrap_options["plugin-op-commands"], local.subinterface_gwlb_endpoint_eastwest[i], local.subinterface_gwlb_endpoint_outbound[i], local.subinterface_gwlb_endpoint_inbound[i]) } bootstrap_options_with_endpoints_mapping = { for i, j in var.vmseries_asgs : i => [ - for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" + for k, v in j.bootstrap_options : k != "plugin-op-commands" ? "${k}=${v}" : "${k}=${local.plugin_op_commands_with_endpoints_mapping[i]}" if v != null ] } } diff --git a/examples/isolated_design_autoscale/variables.tf b/examples/isolated_design_autoscale/variables.tf index c059fe5..6718b23 100644 --- a/examples/isolated_design_autoscale/variables.tf +++ b/examples/isolated_design_autoscale/variables.tf @@ -357,16 +357,19 @@ variable "vmseries_asgs" { default = {} type = map(object({ bootstrap_options = object({ - mgmt-interface-swap = string - plugin-op-commands = string - panorama-server = string - auth-key = string - dgname = string - tplname = string - dhcp-send-hostname = string - dhcp-send-client-id = string - dhcp-accept-server-hostname = string - dhcp-accept-server-domain = string + mgmt-interface-swap = string + plugin-op-commands = string + panorama-server = string + 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 diff --git a/examples/vmseries_standalone/README.md b/examples/vmseries_standalone/README.md index 71094ef..ae64b35 100644 --- a/examples/vmseries_standalone/README.md +++ b/examples/vmseries_standalone/README.md @@ -111,7 +111,7 @@ Use a web browser to access https://x.x.x.x and login with admin and your previo | [name\_prefix](#input\_name\_prefix) | Prefix used in names for the resources (VPCs, EC2 instances, autoscaling groups etc.) | `string` | n/a | yes | | [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 | -| [vmseries](#input\_vmseries) | A map defining VM-Series instances
Following properties are available:
- `instances`: map of VM-Series instances
- `bootstrap_options`: VM-Seriess bootstrap options used to connect to Panorama
- `panos_version`: PAN-OS version used for VM-Series
- `ebs_kms_id`: alias for AWS KMS used for EBS encryption in VM-Series
- `vpc`: key of VPC
Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
}
# 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"

interfaces = {
mgmt = {
device_index = 1
private_ip = "10.100.0.4"
security_group = "vmseries_mgmt"
vpc = "security_vpc"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
eip_allocation_id = null
}
}
}
}
|
map(object({
instances = map(object({
az = string
}))

bootstrap_options = object({
mgmt-interface-swap = string
panorama-server = string
tplname = string
dgname = string
plugin-op-commands = string
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = string
})

panos_version = string
ebs_kms_id = string

vpc = string

interfaces = map(object({
device_index = number
security_group = string
vpc = string
subnet_group = string
create_public_ip = bool
private_ip = map(string)
ipv6_address_count = number
source_dest_check = bool
eip_allocation_id = map(string)
}))
}))
| `{}` | no | +| [vmseries](#input\_vmseries) | A map defining VM-Series instances
Following properties are available:
- `instances`: map of VM-Series instances
- `bootstrap_options`: VM-Seriess bootstrap options used to connect to Panorama
- `panos_version`: PAN-OS version used for VM-Series
- `ebs_kms_id`: alias for AWS KMS used for EBS encryption in VM-Series
- `vpc`: key of VPC
Example:
vmseries = {
vmseries = {
instances = {
"01" = { az = "eu-central-1a" }
}
# 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"

interfaces = {
mgmt = {
device_index = 1
private_ip = "10.100.0.4"
security_group = "vmseries_mgmt"
vpc = "security_vpc"
subnet_group = "mgmt"
create_public_ip = true
source_dest_check = true
eip_allocation_id = null
}
}
}
}
|
map(object({
instances = map(object({
az = string
}))

bootstrap_options = object({
mgmt-interface-swap = string
panorama-server = string
tplname = optional(string)
dgname = string
plugin-op-commands = string
dhcp-send-hostname = string
dhcp-send-client-id = string
dhcp-accept-server-hostname = string
dhcp-accept-server-domain = 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

interfaces = map(object({
device_index = number
security_group = string
vpc = string
subnet_group = string
create_public_ip = bool
private_ip = map(string)
ipv6_address_count = number
source_dest_check = bool
eip_allocation_id = map(string)
}))
}))
| `{}` | no | | [vpcs](#input\_vpcs) | A map defining VPCs with security groups and subnets.

Following properties are available:
- `name`: VPC name
- `cidr`: CIDR for VPC
- `assign_generated_ipv6_cidr_block`: A boolean flag to assign AWS-provided /56 IPv6 CIDR block.
- `nacls`: map of network ACLs
- `security_groups`: map of security groups
- `subnets`: map of subnets with properties:
- `az`: availability zone
- `subnet_group` - key of the subnet group
- `nacl`: key of NACL (can be null)
- `ipv6_index` - choose index for auto-generated IPv6 CIDR, must be null while used with IPv4 only
- `routes`: map of routes with properties:
- `vpc` - key of VPC
- `subnet_group` - key of the subnet group
- `to_cidr` - CIDR for route
- `next_hop_key` - must match keys use to create TGW attachment, IGW, GWLB endpoint or other resources
- `next_hop_type` - internet\_gateway, nat\_gateway, transit\_gateway\_attachment or gwlbe\_endpoint
- `destination_type` - provide destination type. Available options `ipv4`, `ipv6`, `mpl`

Example:
vpcs = {
example_vpc = {
name = "example-spoke-vpc"
cidr = "10.104.0.0/16"
nacls = {
trusted_path_monitoring = {
name = "trusted-path-monitoring"
rules = {
allow_inbound = {
rule_number = 300
egress = false
protocol = "-1"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
from_port = null
to_port = null
}
}
}
}
security_groups = {
example_vm = {
name = "example_vm"
rules = {
all_outbound = {
description = "Permit All traffic outbound"
type = "egress", from_port = "0", to_port = "0", protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
}
subnets = {
"10.104.0.0/24" = { az = "eu-central-1a", subnet_group = "vm", nacl = null }
}
routes = {
vm_default = {
vpc = "app1_vpc"
subnet_group = "app1_vm"
to_cidr = "0.0.0.0/0"
destination_type = "ipv4"
next_hop_key = "app1"
next_hop_type = "transit_gateway_attachment"
}
}
}
}
|
map(object({
name = string
cidr = string
assign_generated_ipv6_cidr_block = bool
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 = optional(list(string))
ipv6_cidr_blocks = optional(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)
ipv6_index = number
local_tags = optional(map(string), {})
}))
routes = map(object({
vpc = string
subnet_group = string
to_cidr = string
destination_type = string
next_hop_key = string
next_hop_type = string
}))
}))
| `{}` | no | ### Outputs diff --git a/examples/vmseries_standalone/example.tfvars b/examples/vmseries_standalone/example.tfvars index 1a2f4c9..ec63010 100644 --- a/examples/vmseries_standalone/example.tfvars +++ b/examples/vmseries_standalone/example.tfvars @@ -65,7 +65,7 @@ vmseries = { "01" = { az = "eu-west-1a" } } - # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license` + # Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license`. Delete map if SCM bootstrap required. bootstrap_options = { mgmt-interface-swap = "disable" panorama-server = "10.10.0.4" # TODO: update here @@ -77,6 +77,21 @@ vmseries = { dhcp-accept-server-hostname = "no" # TODO: update here dhcp-accept-server-domain = "no" # TODO: update here } + /* Uncomment this section if SCM bootstrap required (PAN-OS version 11.0 or higher) + + bootstrap_options = { + mgmt-interface-swap = "disable" + panorama-server = "cloud" # TODO: update here + dgname = "scm_folder_name" # TODO: update here + dhcp-send-hostname = "no" # TODO: update here + dhcp-send-client-id = "no" # TODO: update here + dhcp-accept-server-hostname = "no" # TODO: update here + dhcp-accept-server-domain = "no" # TODO: update here + plugin-op-commands = "advance-routing:enable" # TODO: update here + vm-series-auto-registration-pin-id = "1234ab56-1234-12a3-a1bc-a1bc23456de7" # TODO: update here + vm-series-auto-registration-pin-value = "12ab3c456d78901e2f3abc456d78ef9a" # TODO: update here + } + */ panos_version = "11.1.2-h3" # TODO: update here ebs_kms_id = "alias/aws/ebs" # TODO: update here diff --git a/examples/vmseries_standalone/main.tf b/examples/vmseries_standalone/main.tf index 190ee11..2954103 100644 --- a/examples/vmseries_standalone/main.tf +++ b/examples/vmseries_standalone/main.tf @@ -193,7 +193,7 @@ module "bootstrap" { prefix = var.name_prefix global_tags = var.global_tags - bootstrap_options = merge(each.value.common.bootstrap_options, { hostname = "${var.name_prefix}${each.key}" }) + bootstrap_options = merge({ for k, v in each.value.common.bootstrap_options : k => v if v != null }, { hostname = "${var.name_prefix}${each.key}" }) source_root_directory = "files" } diff --git a/examples/vmseries_standalone/variables.tf b/examples/vmseries_standalone/variables.tf index 7457944..a0dd35b 100644 --- a/examples/vmseries_standalone/variables.tf +++ b/examples/vmseries_standalone/variables.tf @@ -197,15 +197,17 @@ variable "vmseries" { })) bootstrap_options = object({ - mgmt-interface-swap = string - panorama-server = string - tplname = string - dgname = string - plugin-op-commands = string - dhcp-send-hostname = string - dhcp-send-client-id = string - dhcp-accept-server-hostname = string - dhcp-accept-server-domain = string + mgmt-interface-swap = string + panorama-server = string + tplname = optional(string) + dgname = string + plugin-op-commands = string + dhcp-send-hostname = string + dhcp-send-client-id = string + dhcp-accept-server-hostname = string + dhcp-accept-server-domain = string + vm-series-auto-registration-pin-id = optional(string) + vm-series-auto-registration-pin-value = optional(string) }) panos_version = string