Adds support for external SPGs to net-firewall-policy (#2409)

- Added support to reference external SPGs in factories in net-firewall-policy
- Added missing tls_inspect argument to hierarchical and global network firewall policies
- Fixed regional firewall policy rules, removing security profile groups and ngfw actions (given they're not supported)
- Updated copyright
This commit is contained in:
Luca Prete 2024-07-06 13:33:09 +03:00 committed by GitHub
parent afa6e7425c
commit 1bd3380a3f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 194 additions and 14 deletions

View File

@ -253,19 +253,76 @@ issue-1995:
- 1-65535
- protocol: icmp
```
You might need to reference external security profile groups in your firewall rules, using their Terraform ids. For example, `//networksecurity.googleapis.com/${google_network_security_security_profile_group.security_profile_group.id}`. To do so, list your security profile groups in the `security_profile_group_ids` map variable. Then reference them by key from your factories.
```hcl
module "vpc" {
source = "./fabric/modules/net-vpc"
project_id = "my-project"
name = "my-network"
}
resource "google_network_security_security_profile" "security_profile" {
name = "security-profile"
type = "THREAT_PREVENTION"
parent = "organizations/0123456789"
location = "global"
}
resource "google_network_security_security_profile_group" "security_profile_group" {
name = "security-profile-group"
parent = "organizations/0123456789"
location = "global"
description = "Sample security profile group."
threat_prevention_profile = google_network_security_security_profile.security_profile.id
}
module "firewall-policy" {
source = "./fabric/modules/net-firewall-policy"
name = "fw-policy"
parent_id = "my-project"
security_profile_group_ids = {
http-sg = "//networksecurity.googleapis.com/${google_network_security_security_profile_group.security_profile_group.id}"
}
attachments = {
my-vpc = module.vpc.self_link
}
factories_config = {
ingress_rules_file_path = "configs/ingress-spg.yaml"
}
}
# tftest modules=2 resources=8 files=ingress-spg inventory=factory-spg.yaml
```
```yaml
# tftest-file id=ingress-spg path=configs/ingress-spg.yaml
http:
priority: 1000
action: apply_security_profile_group
security_profile_group: http-sg
match:
source_ranges:
- 10.0.0.0/8
layer4_configs:
- protocol: tcp
ports:
- 80
```
<!-- BEGIN TFDOC -->
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [name](variables.tf#L115) | Policy name. | <code>string</code> | ✓ | |
| [parent_id](variables.tf#L121) | Parent node where the policy will be created, `folders/nnn` or `organizations/nnn` for hierarchical policy, project id for a network policy. | <code>string</code> | ✓ | |
| [name](variables.tf#L117) | Policy name. | <code>string</code> | ✓ | |
| [parent_id](variables.tf#L123) | Parent node where the policy will be created, `folders/nnn` or `organizations/nnn` for hierarchical policy, project id for a network policy. | <code>string</code> | ✓ | |
| [attachments](variables.tf#L17) | Ids of the resources to which this policy will be attached, in descriptive name => self link format. Specify folders or organization for hierarchical policy, VPCs for network policy. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [description](variables.tf#L24) | Policy description. | <code>string</code> | | <code>null</code> |
| [egress_rules](variables.tf#L30) | List of egress rule definitions, action can be 'allow', 'deny', 'goto_next' or 'apply_security_profile_group'. The match.layer4configs map is in protocol => optional [ports] format. | <code title="map&#40;object&#40;&#123;&#10; priority &#61; number&#10; action &#61; optional&#40;string, &#34;deny&#34;&#41;&#10; description &#61; optional&#40;string&#41;&#10; disabled &#61; optional&#40;bool, false&#41;&#10; enable_logging &#61; optional&#40;bool&#41;&#10; security_profile_group &#61; optional&#40;string&#41;&#10; target_resources &#61; optional&#40;list&#40;string&#41;&#41;&#10; target_service_accounts &#61; optional&#40;list&#40;string&#41;&#41;&#10; target_tags &#61; optional&#40;list&#40;string&#41;&#41;&#10; match &#61; object&#40;&#123;&#10; address_groups &#61; optional&#40;list&#40;string&#41;&#41;&#10; fqdns &#61; optional&#40;list&#40;string&#41;&#41;&#10; region_codes &#61; optional&#40;list&#40;string&#41;&#41;&#10; threat_intelligences &#61; optional&#40;list&#40;string&#41;&#41;&#10; destination_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; source_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; source_tags &#61; optional&#40;list&#40;string&#41;&#41;&#10; layer4_configs &#61; optional&#40;list&#40;object&#40;&#123;&#10; protocol &#61; optional&#40;string, &#34;all&#34;&#41;&#10; ports &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#91;&#123;&#125;&#93;&#41;&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [factories_config](variables.tf#L67) | Paths to folders for the optional factories. | <code title="object&#40;&#123;&#10; cidr_file_path &#61; optional&#40;string&#41;&#10; egress_rules_file_path &#61; optional&#40;string&#41;&#10; ingress_rules_file_path &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [ingress_rules](variables.tf#L78) | List of ingress rule definitions, action can be 'allow', 'deny', 'goto_next' or 'apply_security_profile_group'. | <code title="map&#40;object&#40;&#123;&#10; priority &#61; number&#10; action &#61; optional&#40;string, &#34;allow&#34;&#41;&#10; description &#61; optional&#40;string&#41;&#10; disabled &#61; optional&#40;bool, false&#41;&#10; enable_logging &#61; optional&#40;bool&#41;&#10; security_profile_group &#61; optional&#40;string&#41;&#10; target_resources &#61; optional&#40;list&#40;string&#41;&#41;&#10; target_service_accounts &#61; optional&#40;list&#40;string&#41;&#41;&#10; target_tags &#61; optional&#40;list&#40;string&#41;&#41;&#10; match &#61; object&#40;&#123;&#10; address_groups &#61; optional&#40;list&#40;string&#41;&#41;&#10; fqdns &#61; optional&#40;list&#40;string&#41;&#41;&#10; region_codes &#61; optional&#40;list&#40;string&#41;&#41;&#10; threat_intelligences &#61; optional&#40;list&#40;string&#41;&#41;&#10; destination_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; source_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; source_tags &#61; optional&#40;list&#40;string&#41;&#41;&#10; layer4_configs &#61; optional&#40;list&#40;object&#40;&#123;&#10; protocol &#61; optional&#40;string, &#34;all&#34;&#41;&#10; ports &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#91;&#123;&#125;&#93;&#41;&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [region](variables.tf#L127) | Policy region. Leave null for hierarchical policy, set to 'global' for a global network policy. | <code>string</code> | | <code>null</code> |
| [egress_rules](variables.tf#L30) | List of egress rule definitions, action can be 'allow', 'deny', 'goto_next' or 'apply_security_profile_group'. The match.layer4configs map is in protocol => optional [ports] format. | <code title="map&#40;object&#40;&#123;&#10; priority &#61; number&#10; action &#61; optional&#40;string, &#34;deny&#34;&#41;&#10; description &#61; optional&#40;string&#41;&#10; disabled &#61; optional&#40;bool, false&#41;&#10; enable_logging &#61; optional&#40;bool&#41;&#10; security_profile_group &#61; optional&#40;string&#41;&#10; target_resources &#61; optional&#40;list&#40;string&#41;&#41;&#10; target_service_accounts &#61; optional&#40;list&#40;string&#41;&#41;&#10; target_tags &#61; optional&#40;list&#40;string&#41;&#41;&#10; tls_inspect &#61; optional&#40;bool, null&#41;&#10; match &#61; object&#40;&#123;&#10; address_groups &#61; optional&#40;list&#40;string&#41;&#41;&#10; fqdns &#61; optional&#40;list&#40;string&#41;&#41;&#10; region_codes &#61; optional&#40;list&#40;string&#41;&#41;&#10; threat_intelligences &#61; optional&#40;list&#40;string&#41;&#41;&#10; destination_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; source_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; source_tags &#61; optional&#40;list&#40;string&#41;&#41;&#10; layer4_configs &#61; optional&#40;list&#40;object&#40;&#123;&#10; protocol &#61; optional&#40;string, &#34;all&#34;&#41;&#10; ports &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#91;&#123;&#125;&#93;&#41;&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [factories_config](variables.tf#L68) | Paths to folders for the optional factories. | <code title="object&#40;&#123;&#10; cidr_file_path &#61; optional&#40;string&#41;&#10; egress_rules_file_path &#61; optional&#40;string&#41;&#10; ingress_rules_file_path &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [ingress_rules](variables.tf#L79) | List of ingress rule definitions, action can be 'allow', 'deny', 'goto_next' or 'apply_security_profile_group'. | <code title="map&#40;object&#40;&#123;&#10; priority &#61; number&#10; action &#61; optional&#40;string, &#34;allow&#34;&#41;&#10; description &#61; optional&#40;string&#41;&#10; disabled &#61; optional&#40;bool, false&#41;&#10; enable_logging &#61; optional&#40;bool&#41;&#10; security_profile_group &#61; optional&#40;string&#41;&#10; target_resources &#61; optional&#40;list&#40;string&#41;&#41;&#10; target_service_accounts &#61; optional&#40;list&#40;string&#41;&#41;&#10; target_tags &#61; optional&#40;list&#40;string&#41;&#41;&#10; tls_inspect &#61; optional&#40;bool, null&#41;&#10; match &#61; object&#40;&#123;&#10; address_groups &#61; optional&#40;list&#40;string&#41;&#41;&#10; fqdns &#61; optional&#40;list&#40;string&#41;&#41;&#10; region_codes &#61; optional&#40;list&#40;string&#41;&#41;&#10; threat_intelligences &#61; optional&#40;list&#40;string&#41;&#41;&#10; destination_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; source_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; source_tags &#61; optional&#40;list&#40;string&#41;&#41;&#10; layer4_configs &#61; optional&#40;list&#40;object&#40;&#123;&#10; protocol &#61; optional&#40;string, &#34;all&#34;&#41;&#10; ports &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#91;&#123;&#125;&#93;&#41;&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [region](variables.tf#L129) | Policy region. Leave null for hierarchical policy, set to 'global' for a global network policy. | <code>string</code> | | <code>null</code> |
| [security_profile_group_ids](variables.tf#L135) | The optional security groups ids to be referenced in factories. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
## Outputs

View File

@ -1,5 +1,5 @@
/**
* Copyright 2023 Google LLC
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -39,6 +39,7 @@ locals {
target_resources = lookup(v, "target_resources", null)
target_service_accounts = lookup(v, "target_service_accounts", null)
target_tags = lookup(v, "target_tags", null)
tls_inspect = lookup(v, "tls_inspect", null)
match = {
address_groups = lookup(v.match, "address_groups", null)
fqdns = lookup(v.match, "fqdns", null)
@ -85,6 +86,7 @@ locals {
target_resources = lookup(v, "target_resources", null)
target_service_accounts = lookup(v, "target_service_accounts", null)
target_tags = lookup(v, "target_tags", null)
tls_inspect = lookup(v, "tls_inspect", null)
match = {
address_groups = lookup(v.match, "address_groups", null)
fqdns = lookup(v.match, "fqdns", null)

View File

@ -1,5 +1,5 @@
/**
* Copyright 2023 Google LLC
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -37,12 +37,16 @@ resource "google_compute_firewall_policy_rule" "hierarchical" {
action = local.rules[each.key].action
description = local.rules[each.key].description
direction = local.rules[each.key].direction
security_profile_group = local.rules[each.key].security_profile_group
disabled = local.rules[each.key].disabled
enable_logging = local.rules[each.key].enable_logging
priority = local.rules[each.key].priority
target_resources = local.rules[each.key].target_resources
target_service_accounts = local.rules[each.key].target_service_accounts
tls_inspect = local.rules[each.key].tls_inspect
security_profile_group = try(
var.security_profile_group_ids[local.rules[each.key].security_profile_group],
local.rules[each.key].security_profile_group
)
match {
dest_ip_ranges = local.rules[each.key].match.destination_ranges
src_ip_ranges = local.rules[each.key].match.source_ranges

View File

@ -1,5 +1,5 @@
/**
* Copyright 2023 Google LLC
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -44,11 +44,15 @@ resource "google_compute_network_firewall_policy_rule" "net-global" {
action = local.rules[each.key].action
description = local.rules[each.key].description
direction = local.rules[each.key].direction
security_profile_group = local.rules[each.key].security_profile_group
disabled = local.rules[each.key].disabled
enable_logging = local.rules[each.key].enable_logging
priority = local.rules[each.key].priority
target_service_accounts = local.rules[each.key].target_service_accounts
tls_inspect = local.rules[each.key].tls_inspect
security_profile_group = try(
var.security_profile_group_ids[local.rules[each.key].security_profile_group],
local.rules[each.key].security_profile_group
)
match {
dest_ip_ranges = local.rules[each.key].match.destination_ranges
src_ip_ranges = local.rules[each.key].match.source_ranges

View File

@ -1,5 +1,5 @@
/**
* Copyright 2023 Google LLC
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -47,7 +47,6 @@ resource "google_compute_region_network_firewall_policy_rule" "net-regional" {
action = local.rules[each.key].action
description = local.rules[each.key].description
direction = local.rules[each.key].direction
security_profile_group = local.rules[each.key].security_profile_group
disabled = local.rules[each.key].disabled
enable_logging = local.rules[each.key].enable_logging
priority = local.rules[each.key].priority

View File

@ -1,5 +1,5 @@
/**
* Copyright 2023 Google LLC
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -39,6 +39,7 @@ variable "egress_rules" {
target_resources = optional(list(string))
target_service_accounts = optional(list(string))
target_tags = optional(list(string))
tls_inspect = optional(bool, null)
match = object({
address_groups = optional(list(string))
fqdns = optional(list(string))
@ -87,6 +88,7 @@ variable "ingress_rules" {
target_resources = optional(list(string))
target_service_accounts = optional(list(string))
target_tags = optional(list(string))
tls_inspect = optional(bool, null)
match = object({
address_groups = optional(list(string))
fqdns = optional(list(string))
@ -129,3 +131,10 @@ variable "region" {
type = string
default = null
}
variable "security_profile_group_ids" {
description = "The optional security groups ids to be referenced in factories."
type = map(string)
nullable = false
default = {}
}

View File

@ -0,0 +1,105 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
values:
google_network_security_security_profile.security_profile:
description: null
labels: null
location: global
name: security-profile
parent: organizations/0123456789
threat_prevention_profile: []
type: THREAT_PREVENTION
google_network_security_security_profile_group.security_profile_group:
description: Sample security profile group.
labels: null
location: global
name: security-profile-group
parent: organizations/0123456789
module.firewall-policy.google_compute_firewall_policy.hierarchical[0]:
description: null
parent: my-project
short_name: fw-policy
module.firewall-policy.google_compute_firewall_policy_association.hierarchical["my-vpc"]:
name: fw-policy-my-vpc
module.firewall-policy.google_compute_firewall_policy_rule.hierarchical["ingress/http"]:
action: apply_security_profile_group
description: null
direction: INGRESS
disabled: false
enable_logging: null
match:
- dest_address_groups: null
dest_fqdns: null
dest_ip_ranges: null
dest_region_codes: null
dest_threat_intelligences: null
layer4_configs:
- ip_protocol: tcp
ports:
- '80'
src_address_groups: null
src_fqdns: null
src_ip_ranges:
- 10.0.0.0/8
src_region_codes: null
src_threat_intelligences: null
priority: 1000
target_resources: null
target_service_accounts: null
tls_inspect: null
module.vpc.google_compute_network.network[0]:
auto_create_subnetworks: false
delete_default_routes_on_create: false
description: Terraform-managed.
enable_ula_internal_ipv6: null
name: my-network
network_firewall_policy_enforcement_order: AFTER_CLASSIC_FIREWALL
project: my-project
routing_mode: GLOBAL
module.vpc.google_compute_route.gateway["private-googleapis"]:
description: Terraform-managed.
dest_range: 199.36.153.8/30
name: my-network-private-googleapis
network: my-network
next_hop_gateway: default-internet-gateway
next_hop_ilb: null
next_hop_instance: null
next_hop_vpn_tunnel: null
priority: 1000
project: my-project
tags: null
module.vpc.google_compute_route.gateway["restricted-googleapis"]:
description: Terraform-managed.
dest_range: 199.36.153.4/30
name: my-network-restricted-googleapis
network: my-network
next_hop_gateway: default-internet-gateway
next_hop_ilb: null
next_hop_instance: null
next_hop_vpn_tunnel: null
priority: 1000
project: my-project
tags: null
counts:
google_compute_firewall_policy: 1
google_compute_firewall_policy_association: 1
google_compute_firewall_policy_rule: 1
google_compute_network: 1
google_compute_route: 2
google_network_security_security_profile: 1
google_network_security_security_profile_group: 1
modules: 2
resources: 8