我正在探索 Terraform,以使用 panos_security_policy 资源自动创建帕洛阿尔托防火墙安全规则。
在添加/修改/删除规则时,将所有这样的安全规则放在 main.tf 中可以按预期工作。
resource "panos_security_policy" "rules" {
rule {
name = "Rule-1"
audit_comment = "Initial config"
source_zones = [panos_zone.dmz.name]
source_addresses = [panos_panorama_address_group.addgrp1.name]
source_users = ["any"]
destination_zones = [panos_zone.internet.name]
destination_addresses = ["any"]
applications = ["ssh"]
services = ["application-default"]
categories = ["any"]
action = "allow"
}
rule {
name = "Rule-2"
audit_comment = "Initial config"
source_zones = [panos_zone.dmz.name]
source_addresses = [panos_panorama_address_group.addgrp1.name]
source_users = ["any"]
destination_zones = [panos_zone.internet.name]
destination_addresses = ["any"]
applications = ["any"]
services = ["any"]
categories = ["any"]
action = "deny"
}
lifecycle {
create_before_destroy = true
}
}
但我不想在 main.tf 中保留有关规则的所有详细信息,特别是如果规则库包含数百条规则。我想将它们保留在变量文件中。我创建了这样的东西:
resource "panos_security_policy" "CreateSecurityRules" {
for_each = var.securityRules
rule {
name = each.value.name
source_zones = each.value.source_zones
source_addresses = each.value.source_addresses
source_users = each.value.source_users
destination_zones = each.value.destination_zones
destination_addresses = each.value.destination_addresses
applications = each.value.applications
services = each.value.services
categories = each.value.categories
action = each.value.action
}
lifecycle {
create_before_destroy = true
}
}
variable securityRules {
type = map(object({
name = string
source_zones = list(string)
source_addresses = list(string)
source_users = list(string)
destination_zones = list(string)
destination_addresses = list(string)
applications = list(string)
services = list(string)
categories = list(string)
action = string
}))
}
rule1 = {
name = "First rule"
source_zones = ["Inside"]
source_addresses = ["any"]
source_users = ["any"]
destination_zones = ["Outside"]
destination_addresses = ["any"]
applications = ["any"]
services = ["application-default"]
categories = ["any"]
action = "allow"
}
rule2 = {
name = "Second rule"
source_zones = ["Inside"]
source_addresses = ["any"]
source_users = ["any"]
destination_zones = ["DMZ"]
destination_addresses = ["any"]
applications = ["any"]
services = ["application-default"]
categories = ["any"]
action = "allow"
}
rule3 = {
name = "Third rule"
source_zones = ["DMZ"]
source_addresses = ["any"]
source_users = ["any"]
destination_zones = ["Outside"]
destination_addresses = ["any"]
applications = ["any"]
services = ["application-default"]
categories = ["any"]
action = "allow"
}
}
不幸的是,我对这段代码没有任何运气。最初,Terraform 设法在防火墙上创建规则,但顺序不正确——这一点非常重要。如果我再次重新运行 Terraform,期望不需要任何更改,但它确实做了一些更改 - 删除一些规则或分配空值。
我认为问题出在地图循环背后的逻辑(附注:我也尝试过列表,但再次没有成功)。
你能帮我解决这个问题吗?
Terraform 设法在防火墙上创建规则,但顺序不正确 - 这非常重要
根据 panos_security_policy,安全规则排序将与其在 terraform 计划文件中的显示方式匹配。
我使用
map(object)
类型的变量和 null_resource
进行了一些快速测试 - 结果将显示在按地图键按字母顺序排序的计划文件中。
考虑以下模块:
variable "securityRules" {
type = map(object({
name = string
}))
}
resource "null_resource" "securityRules" {
for_each = var.securityRules
triggers = {
name = each.value.name
}
}
使用以下
terraform plan
文件运行 terraform.tfvars
:
securityRules = {
"rule100" = {
name = "First rule"
}
"rule2" = {
name = "Second rule"
}
"rule1" = {
name = "Third rule"
}
}
结果是:
Terraform will perform the following actions:
# null_resource.securityRules["rule1"] will be created
+ resource "null_resource" "securityRules" {
+ id = (known after apply)
+ triggers = {
+ "name" = "foo"
}
}
# null_resource.securityRules["rule100"] will be created
+ resource "null_resource" "securityRules" {
+ id = (known after apply)
+ triggers = {
+ "name" = "xyz"
}
}
# null_resource.securityRules["rule2"] will be created
+ resource "null_resource" "securityRules" {
+ id = (known after apply)
+ triggers = {
+ "name" = "bar"
}
}
Plan: 3 to add, 0 to change, 0 to destroy.
哎呀!规则确实按映射键排序,但不是我期望的方式(
rule100
应该是最后一个)。
修复排序和运行
terraform plan
:
securityRules = {
"rule0100" = {
name = "xyz"
}
"rule0002" = {
name = "bar"
}
"rule0001" = {
name = "foo"
}
}
结果如下:
Terraform will perform the following actions:
# null_resource.securityRules["rule0001"] will be created
+ resource "null_resource" "securityRules" {
+ id = (known after apply)
+ triggers = {
+ "name" = "foo"
}
}
# null_resource.securityRules["rule0002"] will be created
+ resource "null_resource" "securityRules" {
+ id = (known after apply)
+ triggers = {
+ "name" = "bar"
}
}
# null_resource.securityRules["rule0100"] will be created
+ resource "null_resource" "securityRules" {
+ id = (known after apply)
+ triggers = {
+ "name" = "xyz"
}
}
Plan: 3 to add, 0 to change, 0 to destroy.
结果现已正确排序。
更改地图中元素的顺序:
securityRules = {
"rule0002" = {
name = "bar"
}
"rule0001" = {
name = "foo"
}
"rule0100" = {
name = "xyz"
}
}
结果与之前相同:
Terraform will perform the following actions:
# null_resource.securityRules["rule0001"] will be created
+ resource "null_resource" "securityRules" {
+ id = (known after apply)
+ triggers = {
+ "name" = "foo"
}
}
# null_resource.securityRules["rule0002"] will be created
+ resource "null_resource" "securityRules" {
+ id = (known after apply)
+ triggers = {
+ "name" = "bar"
}
}
# null_resource.securityRules["rule0100"] will be created
+ resource "null_resource" "securityRules" {
+ id = (known after apply)
+ triggers = {
+ "name" = "xyz"
}
}
Plan: 3 to add, 0 to change, 0 to destroy.