Add support for mirroring rules to modules/net-firewall-policy (#3636)
* Add support for mirroring rules to net-firewall-policy * Split mirroring rules * Add schema * Sort variables
This commit is contained in:
@@ -14,6 +14,8 @@ The module also makes fewer assumptions about implicit defaults, only using one
|
|||||||
- [Hierarchical Policy](#hierarchical-policy)
|
- [Hierarchical Policy](#hierarchical-policy)
|
||||||
- [Global Network policy](#global-network-policy)
|
- [Global Network policy](#global-network-policy)
|
||||||
- [Regional Network policy](#regional-network-policy)
|
- [Regional Network policy](#regional-network-policy)
|
||||||
|
- [Packet Mirroring Rules](#packet-mirroring-rules)
|
||||||
|
- [Packet Mirroring Rules](#packet-mirroring-rules)
|
||||||
- [Factory](#factory)
|
- [Factory](#factory)
|
||||||
- [Firewall Rule Factory Schema](#firewall-rule-factory-schema)
|
- [Firewall Rule Factory Schema](#firewall-rule-factory-schema)
|
||||||
- [Dynamic Rule Matching](#dynamic-rule-matching)
|
- [Dynamic Rule Matching](#dynamic-rule-matching)
|
||||||
@@ -168,6 +170,60 @@ module "firewall-policy" {
|
|||||||
# tftest modules=2 resources=8 inventory=regional-net.yaml
|
# tftest modules=2 resources=8 inventory=regional-net.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Packet Mirroring Rules
|
||||||
|
|
||||||
|
### Packet Mirroring Rules
|
||||||
|
Packet mirroring rules can be defined using the `ingress_mirroring_rules` and `egress_mirroring_rules` variables. This is supported only for Global Network Policies.
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
resource "google_network_security_security_profile" "default" {
|
||||||
|
provider = google-beta
|
||||||
|
name = "sec-profile"
|
||||||
|
parent = var.organization_id
|
||||||
|
type = "CUSTOM_MIRRORING"
|
||||||
|
|
||||||
|
custom_mirroring_profile {
|
||||||
|
mirroring_endpoint_group = "xxx"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_network_security_security_profile_group" "default" {
|
||||||
|
provider = google-beta
|
||||||
|
name = "sec-profile-group"
|
||||||
|
parent = var.organization_id
|
||||||
|
custom_mirroring_profile = google_network_security_security_profile.default.id
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module "firewall-policy" {
|
||||||
|
source = "./fabric/modules/net-firewall-policy"
|
||||||
|
name = "test-mirroring"
|
||||||
|
parent_id = "my-project"
|
||||||
|
region = "global"
|
||||||
|
attachments = {
|
||||||
|
my-vpc = var.vpc.self_link
|
||||||
|
}
|
||||||
|
security_profile_group_ids = {
|
||||||
|
my-spg = "//networksecurity.googleapis.com/${google_network_security_security_profile_group.default.id}"
|
||||||
|
}
|
||||||
|
ingress_mirroring_rules = {
|
||||||
|
rule-1 = {
|
||||||
|
priority = 1000
|
||||||
|
action = "mirror"
|
||||||
|
description = "Mirror all traffic"
|
||||||
|
match = {
|
||||||
|
source_ranges = ["0.0.0.0/0"]
|
||||||
|
layer4_configs = [
|
||||||
|
{ protocol = "tcp", ports = ["80", "443"] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
security_profile_group = "//networksecurity.googleapis.com/${google_network_security_security_profile_group.default.id}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# tftest inventory=mirroring.yaml
|
||||||
|
```
|
||||||
|
|
||||||
### Factory
|
### Factory
|
||||||
|
|
||||||
Similarly to other modules, a rules factory is also included here to allow route management via descriptive configuration files.
|
Similarly to other modules, a rules factory is also included here to allow route management via descriptive configuration files.
|
||||||
@@ -177,6 +233,8 @@ Factory configuration is via three optional attributes in the `rules_factory_con
|
|||||||
- `cidr_file_path` specifying the path to a mapping of logical names to CIDR ranges, used for source and destination ranges in rules when available
|
- `cidr_file_path` specifying the path to a mapping of logical names to CIDR ranges, used for source and destination ranges in rules when available
|
||||||
- `egress_rules_file_path` specifying the path to the egress rules file
|
- `egress_rules_file_path` specifying the path to the egress rules file
|
||||||
- `ingress_rules_file_path` specifying the path to the ingress rules file
|
- `ingress_rules_file_path` specifying the path to the ingress rules file
|
||||||
|
- `ingress_mirroring_rules_file_path` specifying the path to the mirroring rules file
|
||||||
|
- `egress_mirroring_rules_file_path` specifying the path to the mirroring rules file
|
||||||
|
|
||||||
Factory rules are merged with rules declared in code, with the latter taking precedence where both use the same key.
|
Factory rules are merged with rules declared in code, with the latter taking precedence where both use the same key.
|
||||||
Also, the factory applies implicit defaults: `action` defaults to `deny` for egress and `allow` for ingress, while omitting `layer4_configs` makes the rule match all protocols.
|
Also, the factory applies implicit defaults: `action` defaults to `deny` for egress and `allow` for ingress, while omitting `layer4_configs` makes the rule match all protocols.
|
||||||
@@ -260,6 +318,35 @@ issue-1995:
|
|||||||
# tftest-file id=ingress path=configs/ingress.yaml schema=firewall-policy-rules.schema.json
|
# tftest-file id=ingress path=configs/ingress.yaml schema=firewall-policy-rules.schema.json
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
icmp:
|
||||||
|
priority: 1000
|
||||||
|
match:
|
||||||
|
source_ranges:
|
||||||
|
- 10.0.0.0/8
|
||||||
|
layer4_configs:
|
||||||
|
- protocol: icmp
|
||||||
|
issue-1995:
|
||||||
|
priority: 10020
|
||||||
|
description: Allow intra-cluster communication required by k8s networking model
|
||||||
|
enable_logging: true
|
||||||
|
target_service_accounts:
|
||||||
|
- sa-gke-cluster@burner-project.iam.gserviceaccount.com
|
||||||
|
match:
|
||||||
|
source_ranges:
|
||||||
|
- gke-nodes-range
|
||||||
|
layer4_configs:
|
||||||
|
- protocol: tcp
|
||||||
|
ports:
|
||||||
|
- 1-65535
|
||||||
|
- protocol: udp
|
||||||
|
ports:
|
||||||
|
- 1-65535
|
||||||
|
- protocol: icmp
|
||||||
|
# tftest-file id=ingress path=configs/ingress.yaml schema=firewall-policy-rules.schema.json
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
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.
|
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
|
```hcl
|
||||||
@@ -272,33 +359,54 @@ module "vpc" {
|
|||||||
resource "google_network_security_security_profile" "security_profile" {
|
resource "google_network_security_security_profile" "security_profile" {
|
||||||
name = "security-profile"
|
name = "security-profile"
|
||||||
type = "THREAT_PREVENTION"
|
type = "THREAT_PREVENTION"
|
||||||
parent = "organizations/0123456789"
|
parent = var.organization_id
|
||||||
location = "global"
|
location = "global"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_network_security_security_profile_group" "security_profile_group" {
|
resource "google_network_security_security_profile_group" "security_profile_group" {
|
||||||
name = "security-profile-group"
|
name = "security-profile-group"
|
||||||
parent = "organizations/0123456789"
|
parent = var.organization_id
|
||||||
location = "global"
|
location = "global"
|
||||||
description = "Sample security profile group."
|
description = "Sample security profile group."
|
||||||
threat_prevention_profile = google_network_security_security_profile.security_profile.id
|
threat_prevention_profile = google_network_security_security_profile.security_profile.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "google_network_security_security_profile" "mirror_profile" {
|
||||||
|
provider = google-beta
|
||||||
|
name = "sec-profile"
|
||||||
|
parent = var.organization_id
|
||||||
|
type = "CUSTOM_MIRRORING"
|
||||||
|
|
||||||
|
custom_mirroring_profile {
|
||||||
|
mirroring_endpoint_group = "xxx"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_network_security_security_profile_group" "mirror_profile_group" {
|
||||||
|
provider = google-beta
|
||||||
|
name = "sec-profile-group"
|
||||||
|
parent = var.organization_id
|
||||||
|
custom_mirroring_profile = google_network_security_security_profile.mirror_profile.id
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module "firewall-policy" {
|
module "firewall-policy" {
|
||||||
source = "./fabric/modules/net-firewall-policy"
|
source = "./fabric/modules/net-firewall-policy"
|
||||||
name = "fw-policy"
|
name = "fw-policy"
|
||||||
parent_id = "my-project"
|
parent_id = "my-project"
|
||||||
security_profile_group_ids = {
|
security_profile_group_ids = {
|
||||||
http-sg = "//networksecurity.googleapis.com/${google_network_security_security_profile_group.security_profile_group.id}"
|
http-sg = "//networksecurity.googleapis.com/${google_network_security_security_profile_group.security_profile_group.id}"
|
||||||
|
mirror-sg = "//networksecurity.googleapis.com/${google_network_security_security_profile_group.mirror_profile_group.id}"
|
||||||
}
|
}
|
||||||
attachments = {
|
attachments = {
|
||||||
my-vpc = module.vpc.self_link
|
my-vpc = module.vpc.self_link
|
||||||
}
|
}
|
||||||
factories_config = {
|
factories_config = {
|
||||||
ingress_rules_file_path = "configs/ingress-spg.yaml"
|
ingress_rules_file_path = "configs/ingress-spg.yaml"
|
||||||
|
ingress_mirroring_rules_file_path = "configs/mirror-spg.yaml"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# tftest modules=2 resources=9 files=ingress-spg inventory=factory-spg.yaml
|
# tftest modules=2 resources=11 files=ingress-spg,mirror-spg inventory=factory-spg.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -316,6 +424,21 @@ http:
|
|||||||
- 80
|
- 80
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# tftest-file id=mirror-spg path=configs/mirror-spg.yaml schema=firewall-policy-mirroring-rules.schema.json
|
||||||
|
mirror-ssh:
|
||||||
|
priority: 1000
|
||||||
|
action: mirror
|
||||||
|
security_profile_group: mirror-sg
|
||||||
|
match:
|
||||||
|
source_ranges:
|
||||||
|
- 10.0.0.0/8
|
||||||
|
layer4_configs:
|
||||||
|
- protocol: tcp
|
||||||
|
ports:
|
||||||
|
- 22
|
||||||
|
```
|
||||||
|
|
||||||
#### Firewall Rule Factory Schema
|
#### Firewall Rule Factory Schema
|
||||||
|
|
||||||
The following schema outlines all available fields for defining a rule within a factory YAML file. Use this as a reference, and note the inline comments for fields that apply only to specific policy types.
|
The following schema outlines all available fields for defining a rule within a factory YAML file. Use this as a reference, and note the inline comments for fields that apply only to specific policy types.
|
||||||
@@ -386,16 +509,18 @@ The following variable is defined at the top level of the rule (not within the `
|
|||||||
|
|
||||||
| name | description | type | required | default |
|
| name | description | type | required | default |
|
||||||
|---|---|:---:|:---:|:---:|
|
|---|---|:---:|:---:|:---:|
|
||||||
| [name](variables.tf#L133) | Policy name. | <code>string</code> | ✓ | |
|
| [name](variables.tf#L197) | Policy name. | <code>string</code> | ✓ | |
|
||||||
| [parent_id](variables.tf#L139) | 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> | ✓ | |
|
| [parent_id](variables.tf#L203) | 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(string)</code> | | <code>{}</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(string)</code> | | <code>{}</code> |
|
||||||
| [context](variables.tf#L24) | Context-specific interpolations. | <code title="object({ cidr_ranges = optional(map(string), {}) cidr_ranges_sets = optional(map(list(string)), {}) folder_ids = optional(map(string), {}) iam_principals = optional(map(string), {}) locations = optional(map(string), {}) networks = optional(map(string), {}) project_ids = optional(map(string), {}) tag_values = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> |
|
| [context](variables.tf#L24) | Context-specific interpolations. | <code title="object({ cidr_ranges = optional(map(string), {}) cidr_ranges_sets = optional(map(list(string)), {}) folder_ids = optional(map(string), {}) iam_principals = optional(map(string), {}) locations = optional(map(string), {}) networks = optional(map(string), {}) project_ids = optional(map(string), {}) tag_values = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> |
|
||||||
| [description](variables.tf#L40) | Policy description. | <code>string</code> | | <code>null</code> |
|
| [description](variables.tf#L40) | Policy description. | <code>string</code> | | <code>null</code> |
|
||||||
| [egress_rules](variables.tf#L46) | 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(object({ priority = number action = optional(string, "deny") description = optional(string) disabled = optional(bool, false) enable_logging = optional(bool) security_profile_group = optional(string) 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)) region_codes = optional(list(string)) threat_intelligences = optional(list(string)) destination_ranges = optional(list(string)) source_ranges = optional(list(string)) source_tags = optional(list(string)) layer4_configs = optional(list(object({ protocol = optional(string, "all") ports = optional(list(string)) })), [{}]) }) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [egress_mirroring_rules](variables.tf#L46) | List of egress packet mirroring rule definitions, action can be 'mirror', 'do_not_mirror', or 'goto_next'. | <code title="map(object({ priority = number action = optional(string, "mirror") description = optional(string) disabled = optional(bool, false) security_profile_group = optional(string) target_tags = optional(list(string)) tls_inspect = optional(bool, null) match = object({ destination_ranges = optional(list(string)) source_ranges = optional(list(string)) source_tags = optional(list(string)) layer4_configs = optional(list(object({ protocol = optional(string, "all") ports = optional(list(string)) })), [{}]) }) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [factories_config](variables.tf#L84) | Paths to folders for the optional factories. | <code title="object({ cidr_file_path = optional(string) egress_rules_file_path = optional(string) ingress_rules_file_path = optional(string) })">object({…})</code> | | <code>{}</code> |
|
| [egress_rules](variables.tf#L77) | 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(object({ priority = number action = optional(string, "deny") description = optional(string) disabled = optional(bool, false) enable_logging = optional(bool) security_profile_group = optional(string) 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)) region_codes = optional(list(string)) threat_intelligences = optional(list(string)) destination_ranges = optional(list(string)) source_ranges = optional(list(string)) source_tags = optional(list(string)) layer4_configs = optional(list(object({ protocol = optional(string, "all") ports = optional(list(string)) })), [{}]) }) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [ingress_rules](variables.tf#L95) | List of ingress rule definitions, action can be 'allow', 'deny', 'goto_next' or 'apply_security_profile_group'. | <code title="map(object({ priority = number action = optional(string, "allow") description = optional(string) disabled = optional(bool, false) enable_logging = optional(bool) security_profile_group = optional(string) 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)) region_codes = optional(list(string)) threat_intelligences = optional(list(string)) destination_ranges = optional(list(string)) source_ranges = optional(list(string)) source_tags = optional(list(string)) layer4_configs = optional(list(object({ protocol = optional(string, "all") ports = optional(list(string)) })), [{}]) }) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [factories_config](variables.tf#L115) | Paths to folders for the optional factories. | <code title="object({ cidr_file_path = optional(string) egress_rules_file_path = optional(string) ingress_rules_file_path = optional(string) ingress_mirroring_rules_file_path = optional(string) egress_mirroring_rules_file_path = optional(string) })">object({…})</code> | | <code>{}</code> |
|
||||||
| [region](variables.tf#L145) | Policy region. Leave null for hierarchical policy, set to 'global' for a global network policy. | <code>string</code> | | <code>null</code> |
|
| [ingress_mirroring_rules](variables.tf#L128) | List of ingress packet mirroring rule definitions, action can be 'mirror', 'do_not_mirror', or 'goto_next'. | <code title="map(object({ priority = number action = optional(string, "mirror") description = optional(string) disabled = optional(bool, false) security_profile_group = optional(string) target_tags = optional(list(string)) tls_inspect = optional(bool, null) match = object({ destination_ranges = optional(list(string)) source_ranges = optional(list(string)) source_tags = optional(list(string)) layer4_configs = optional(list(object({ protocol = optional(string, "all") ports = optional(list(string)) })), [{}]) }) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [security_profile_group_ids](variables.tf#L151) | The optional security groups ids to be referenced in factories. | <code>map(string)</code> | | <code>{}</code> |
|
| [ingress_rules](variables.tf#L159) | List of ingress rule definitions, action can be 'allow', 'deny', 'goto_next' or 'apply_security_profile_group'. | <code title="map(object({ priority = number action = optional(string, "allow") description = optional(string) disabled = optional(bool, false) enable_logging = optional(bool) security_profile_group = optional(string) 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)) region_codes = optional(list(string)) threat_intelligences = optional(list(string)) destination_ranges = optional(list(string)) source_ranges = optional(list(string)) source_tags = optional(list(string)) layer4_configs = optional(list(object({ protocol = optional(string, "all") ports = optional(list(string)) })), [{}]) }) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
|
| [region](variables.tf#L209) | 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#L215) | The optional security groups ids to be referenced in factories. | <code>map(string)</code> | | <code>{}</code> |
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2024 Google LLC
|
* Copyright 2026 Google LLC
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -25,6 +25,16 @@ locals {
|
|||||||
yamldecode(file(pathexpand(var.factories_config.ingress_rules_file_path))),
|
yamldecode(file(pathexpand(var.factories_config.ingress_rules_file_path))),
|
||||||
{}), tomap({})
|
{}), tomap({})
|
||||||
)
|
)
|
||||||
|
_factory_mirroring_rules_egress = coalesce(
|
||||||
|
try(
|
||||||
|
yamldecode(file(pathexpand(var.factories_config.egress_mirroring_rules_file_path))),
|
||||||
|
{}), tomap({})
|
||||||
|
)
|
||||||
|
_factory_mirroring_rules_ingress = coalesce(
|
||||||
|
try(
|
||||||
|
yamldecode(file(pathexpand(var.factories_config.ingress_mirroring_rules_file_path))),
|
||||||
|
{}), tomap({})
|
||||||
|
)
|
||||||
factory_cidrs = coalesce(
|
factory_cidrs = coalesce(
|
||||||
try(
|
try(
|
||||||
yamldecode(file(pathexpand(var.factories_config.cidr_file_path))),
|
yamldecode(file(pathexpand(var.factories_config.cidr_file_path))),
|
||||||
@@ -124,4 +134,84 @@ locals {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
factory_mirroring_ingress_rules = {
|
||||||
|
for k, v in local._factory_mirroring_rules_ingress : "mirror/ingress/${k}" => {
|
||||||
|
direction = "INGRESS"
|
||||||
|
name = k
|
||||||
|
priority = v.priority
|
||||||
|
action = lookup(v, "action", "mirror")
|
||||||
|
description = lookup(v, "description", null)
|
||||||
|
disabled = lookup(v, "disabled", false)
|
||||||
|
security_profile_group = lookup(v, "security_profile_group", null)
|
||||||
|
target_tags = lookup(v, "target_tags", null)
|
||||||
|
tls_inspect = lookup(v, "tls_inspect", null)
|
||||||
|
match = {
|
||||||
|
destination_ranges = (
|
||||||
|
lookup(v.match, "destination_ranges", null) == null
|
||||||
|
? null
|
||||||
|
: flatten([
|
||||||
|
for r in v.match.destination_ranges :
|
||||||
|
try(local.factory_cidrs[r], r)
|
||||||
|
])
|
||||||
|
)
|
||||||
|
source_ranges = (
|
||||||
|
lookup(v.match, "source_ranges", null) == null
|
||||||
|
? null
|
||||||
|
: flatten([
|
||||||
|
for r in v.match.source_ranges :
|
||||||
|
try(local.factory_cidrs[r], r)
|
||||||
|
])
|
||||||
|
)
|
||||||
|
source_tags = lookup(v.match, "source_tags", null)
|
||||||
|
layer4_configs = (
|
||||||
|
lookup(v.match, "layer4_configs", null) == null
|
||||||
|
? [{ protocol = "all", ports = null }]
|
||||||
|
: [
|
||||||
|
for c in v.match.layer4_configs :
|
||||||
|
merge({ protocol = "all", ports = [] }, c)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
factory_mirroring_egress_rules = {
|
||||||
|
for k, v in local._factory_mirroring_rules_egress : "mirror/egress/${k}" => {
|
||||||
|
direction = "EGRESS"
|
||||||
|
name = k
|
||||||
|
priority = v.priority
|
||||||
|
action = lookup(v, "action", "mirror")
|
||||||
|
description = lookup(v, "description", null)
|
||||||
|
disabled = lookup(v, "disabled", false)
|
||||||
|
security_profile_group = lookup(v, "security_profile_group", null)
|
||||||
|
target_tags = lookup(v, "target_tags", null)
|
||||||
|
tls_inspect = lookup(v, "tls_inspect", null)
|
||||||
|
match = {
|
||||||
|
destination_ranges = (
|
||||||
|
lookup(v.match, "destination_ranges", null) == null
|
||||||
|
? null
|
||||||
|
: flatten([
|
||||||
|
for r in v.match.destination_ranges :
|
||||||
|
try(local.factory_cidrs[r], r)
|
||||||
|
])
|
||||||
|
)
|
||||||
|
source_ranges = (
|
||||||
|
lookup(v.match, "source_ranges", null) == null
|
||||||
|
? null
|
||||||
|
: flatten([
|
||||||
|
for r in v.match.source_ranges :
|
||||||
|
try(local.factory_cidrs[r], r)
|
||||||
|
])
|
||||||
|
)
|
||||||
|
source_tags = lookup(v.match, "source_tags", null)
|
||||||
|
layer4_configs = (
|
||||||
|
lookup(v.match, "layer4_configs", null) == null
|
||||||
|
? [{ protocol = "all", ports = null }]
|
||||||
|
: [
|
||||||
|
for c in v.match.layer4_configs :
|
||||||
|
merge({ protocol = "all", ports = [] }, c)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2023 Google LLC
|
* Copyright 2026 Google LLC
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -23,6 +23,14 @@ locals {
|
|||||||
for name, rule in merge(var.ingress_rules) :
|
for name, rule in merge(var.ingress_rules) :
|
||||||
"ingress/${name}" => merge(rule, { name = name, direction = "INGRESS" })
|
"ingress/${name}" => merge(rule, { name = name, direction = "INGRESS" })
|
||||||
}
|
}
|
||||||
|
_mirroring_rules_egress = {
|
||||||
|
for name, rule in merge(var.egress_mirroring_rules) :
|
||||||
|
"mirror/egress/${name}" => merge(rule, { name = name, direction = "EGRESS" })
|
||||||
|
}
|
||||||
|
_mirroring_rules_ingress = {
|
||||||
|
for name, rule in merge(var.ingress_mirroring_rules) :
|
||||||
|
"mirror/ingress/${name}" => merge(rule, { name = name, direction = "INGRESS" })
|
||||||
|
}
|
||||||
ctx = {
|
ctx = {
|
||||||
for k, v in var.context : k => {
|
for k, v in var.context : k => {
|
||||||
for kk, vv in v : "${local.ctx_p}${k}:${kk}" => vv
|
for kk, vv in v : "${local.ctx_p}${k}:${kk}" => vv
|
||||||
@@ -33,6 +41,10 @@ locals {
|
|||||||
local.factory_egress_rules, local.factory_ingress_rules,
|
local.factory_egress_rules, local.factory_ingress_rules,
|
||||||
local._rules_egress, local._rules_ingress
|
local._rules_egress, local._rules_ingress
|
||||||
)
|
)
|
||||||
|
mirroring_rules = merge(
|
||||||
|
local.factory_mirroring_egress_rules, local.factory_mirroring_ingress_rules,
|
||||||
|
local._mirroring_rules_egress, local._mirroring_rules_ingress
|
||||||
|
)
|
||||||
# do not depend on the parent id as that might be dynamic and prevent count
|
# do not depend on the parent id as that might be dynamic and prevent count
|
||||||
use_hierarchical = var.region == null
|
use_hierarchical = var.region == null
|
||||||
use_regional = !local.use_hierarchical && var.region != "global"
|
use_regional = !local.use_hierarchical && var.region != "global"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2024 Google LLC
|
* Copyright 2026 Google LLC
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -146,3 +146,71 @@ resource "google_compute_network_firewall_policy_rule" "net-global" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "google_compute_network_firewall_policy_packet_mirroring_rule" "net-global" {
|
||||||
|
provider = google-beta
|
||||||
|
for_each = toset(
|
||||||
|
!local.use_hierarchical && !local.use_regional
|
||||||
|
? keys(local.mirroring_rules)
|
||||||
|
: []
|
||||||
|
)
|
||||||
|
project = lookup(local.ctx.project_ids, var.parent_id, var.parent_id)
|
||||||
|
firewall_policy = google_compute_network_firewall_policy.net-global[0].name
|
||||||
|
rule_name = local.mirroring_rules[each.key].name
|
||||||
|
action = local.mirroring_rules[each.key].action
|
||||||
|
description = local.mirroring_rules[each.key].description
|
||||||
|
direction = local.mirroring_rules[each.key].direction
|
||||||
|
disabled = local.mirroring_rules[each.key].disabled
|
||||||
|
priority = local.mirroring_rules[each.key].priority
|
||||||
|
tls_inspect = local.mirroring_rules[each.key].tls_inspect
|
||||||
|
|
||||||
|
security_profile_group = try(
|
||||||
|
var.security_profile_group_ids[local.mirroring_rules[each.key].security_profile_group],
|
||||||
|
local.mirroring_rules[each.key].security_profile_group
|
||||||
|
)
|
||||||
|
|
||||||
|
match {
|
||||||
|
dest_ip_ranges = (
|
||||||
|
local.mirroring_rules[each.key].match.destination_ranges == null
|
||||||
|
? null
|
||||||
|
: distinct(flatten([
|
||||||
|
for r in local.mirroring_rules[each.key].match.destination_ranges : try(
|
||||||
|
local.ctx.cidr_ranges_sets[r],
|
||||||
|
local.ctx.cidr_ranges[r],
|
||||||
|
r
|
||||||
|
)
|
||||||
|
]))
|
||||||
|
)
|
||||||
|
src_ip_ranges = (
|
||||||
|
local.mirroring_rules[each.key].match.source_ranges == null
|
||||||
|
? null
|
||||||
|
: distinct(flatten([
|
||||||
|
for r in local.mirroring_rules[each.key].match.source_ranges : try(
|
||||||
|
local.ctx.cidr_ranges_sets[r],
|
||||||
|
local.ctx.cidr_ranges[r],
|
||||||
|
r
|
||||||
|
)
|
||||||
|
]))
|
||||||
|
)
|
||||||
|
dynamic "layer4_configs" {
|
||||||
|
for_each = local.mirroring_rules[each.key].match.layer4_configs
|
||||||
|
content {
|
||||||
|
ip_protocol = layer4_configs.value.protocol
|
||||||
|
ports = layer4_configs.value.ports
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
dynamic "target_secure_tags" {
|
||||||
|
for_each = toset(
|
||||||
|
local.mirroring_rules[each.key].target_tags == null
|
||||||
|
? []
|
||||||
|
: local.mirroring_rules[each.key].target_tags
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
name = lookup(
|
||||||
|
local.ctx.tag_values, target_secure_tags.value, target_secure_tags.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"title": "Firewall Policy Mirroring Rules",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"patternProperties": {
|
||||||
|
"^[a-z0-9_-]+$": {
|
||||||
|
"$ref": "#/$defs/rule"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"$defs": {
|
||||||
|
"rule": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": [
|
||||||
|
"priority"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"priority": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"mirror",
|
||||||
|
"do_not_mirror",
|
||||||
|
"goto_next"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"security_profile_group": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"target_tags": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tls_inspect": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"match": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"destination_ranges": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"source_ranges": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"source_tags": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"layer4_configs": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"protocol": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"ports": {
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2024 Google LLC
|
* Copyright 2026 Google LLC
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -43,6 +43,37 @@ variable "description" {
|
|||||||
default = null
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "egress_mirroring_rules" {
|
||||||
|
description = "List of egress packet mirroring rule definitions, action can be 'mirror', 'do_not_mirror', or 'goto_next'."
|
||||||
|
type = map(object({
|
||||||
|
priority = number
|
||||||
|
action = optional(string, "mirror")
|
||||||
|
description = optional(string)
|
||||||
|
disabled = optional(bool, false)
|
||||||
|
security_profile_group = optional(string)
|
||||||
|
target_tags = optional(list(string))
|
||||||
|
tls_inspect = optional(bool, null)
|
||||||
|
match = object({
|
||||||
|
destination_ranges = optional(list(string))
|
||||||
|
source_ranges = optional(list(string))
|
||||||
|
source_tags = optional(list(string))
|
||||||
|
layer4_configs = optional(list(object({
|
||||||
|
protocol = optional(string, "all")
|
||||||
|
ports = optional(list(string))
|
||||||
|
})), [{}])
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
default = {}
|
||||||
|
nullable = false
|
||||||
|
validation {
|
||||||
|
condition = alltrue([
|
||||||
|
for k, v in var.egress_mirroring_rules :
|
||||||
|
contains(["mirror", "do_not_mirror", "goto_next"], v.action)
|
||||||
|
])
|
||||||
|
error_message = "Action can only be one of 'mirror', 'do_not_mirror' or 'goto_next'."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
variable "egress_rules" {
|
variable "egress_rules" {
|
||||||
description = "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."
|
description = "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."
|
||||||
type = map(object({
|
type = map(object({
|
||||||
@@ -84,14 +115,47 @@ variable "egress_rules" {
|
|||||||
variable "factories_config" {
|
variable "factories_config" {
|
||||||
description = "Paths to folders for the optional factories."
|
description = "Paths to folders for the optional factories."
|
||||||
type = object({
|
type = object({
|
||||||
cidr_file_path = optional(string)
|
cidr_file_path = optional(string)
|
||||||
egress_rules_file_path = optional(string)
|
egress_rules_file_path = optional(string)
|
||||||
ingress_rules_file_path = optional(string)
|
ingress_rules_file_path = optional(string)
|
||||||
|
ingress_mirroring_rules_file_path = optional(string)
|
||||||
|
egress_mirroring_rules_file_path = optional(string)
|
||||||
})
|
})
|
||||||
nullable = false
|
nullable = false
|
||||||
default = {}
|
default = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "ingress_mirroring_rules" {
|
||||||
|
description = "List of ingress packet mirroring rule definitions, action can be 'mirror', 'do_not_mirror', or 'goto_next'."
|
||||||
|
type = map(object({
|
||||||
|
priority = number
|
||||||
|
action = optional(string, "mirror")
|
||||||
|
description = optional(string)
|
||||||
|
disabled = optional(bool, false)
|
||||||
|
security_profile_group = optional(string)
|
||||||
|
target_tags = optional(list(string))
|
||||||
|
tls_inspect = optional(bool, null)
|
||||||
|
match = object({
|
||||||
|
destination_ranges = optional(list(string))
|
||||||
|
source_ranges = optional(list(string))
|
||||||
|
source_tags = optional(list(string))
|
||||||
|
layer4_configs = optional(list(object({
|
||||||
|
protocol = optional(string, "all")
|
||||||
|
ports = optional(list(string))
|
||||||
|
})), [{}])
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
default = {}
|
||||||
|
nullable = false
|
||||||
|
validation {
|
||||||
|
condition = alltrue([
|
||||||
|
for k, v in var.ingress_mirroring_rules :
|
||||||
|
contains(["mirror", "do_not_mirror", "goto_next"], v.action)
|
||||||
|
])
|
||||||
|
error_message = "Action can only be one of 'mirror', 'do_not_mirror' or 'goto_next'."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
variable "ingress_rules" {
|
variable "ingress_rules" {
|
||||||
description = "List of ingress rule definitions, action can be 'allow', 'deny', 'goto_next' or 'apply_security_profile_group'."
|
description = "List of ingress rule definitions, action can be 'allow', 'deny', 'goto_next' or 'apply_security_profile_group'."
|
||||||
type = map(object({
|
type = map(object({
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright 2024 Google LLC
|
# Copyright 2026 Google LLC
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -13,26 +13,74 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
values:
|
values:
|
||||||
google_network_security_security_profile.security_profile:
|
google_network_security_security_profile.mirror_profile:
|
||||||
|
custom_intercept_profile: []
|
||||||
|
custom_mirroring_profile:
|
||||||
|
- mirroring_deployment_groups: null
|
||||||
|
mirroring_endpoint_group: xxx
|
||||||
description: null
|
description: null
|
||||||
|
effective_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
|
labels: null
|
||||||
|
location: global
|
||||||
|
name: sec-profile
|
||||||
|
parent: organizations/1122334455
|
||||||
|
terraform_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
|
threat_prevention_profile: []
|
||||||
|
timeouts: null
|
||||||
|
type: CUSTOM_MIRRORING
|
||||||
|
url_filtering_profile: []
|
||||||
|
google_network_security_security_profile.security_profile:
|
||||||
|
custom_intercept_profile: []
|
||||||
|
custom_mirroring_profile: []
|
||||||
|
description: null
|
||||||
|
effective_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
labels: null
|
labels: null
|
||||||
location: global
|
location: global
|
||||||
name: security-profile
|
name: security-profile
|
||||||
parent: organizations/0123456789
|
parent: organizations/1122334455
|
||||||
|
terraform_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
threat_prevention_profile: []
|
threat_prevention_profile: []
|
||||||
|
timeouts: null
|
||||||
type: THREAT_PREVENTION
|
type: THREAT_PREVENTION
|
||||||
|
google_network_security_security_profile_group.mirror_profile_group:
|
||||||
|
custom_intercept_profile: null
|
||||||
|
description: null
|
||||||
|
effective_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
|
labels: null
|
||||||
|
location: global
|
||||||
|
name: sec-profile-group
|
||||||
|
parent: organizations/1122334455
|
||||||
|
terraform_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
|
threat_prevention_profile: null
|
||||||
|
timeouts: null
|
||||||
|
url_filtering_profile: null
|
||||||
google_network_security_security_profile_group.security_profile_group:
|
google_network_security_security_profile_group.security_profile_group:
|
||||||
|
custom_intercept_profile: null
|
||||||
|
custom_mirroring_profile: null
|
||||||
description: Sample security profile group.
|
description: Sample security profile group.
|
||||||
|
effective_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
labels: null
|
labels: null
|
||||||
location: global
|
location: global
|
||||||
name: security-profile-group
|
name: security-profile-group
|
||||||
parent: organizations/0123456789
|
parent: organizations/1122334455
|
||||||
|
terraform_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
|
timeouts: null
|
||||||
module.firewall-policy.google_compute_firewall_policy.hierarchical[0]:
|
module.firewall-policy.google_compute_firewall_policy.hierarchical[0]:
|
||||||
description: null
|
description: null
|
||||||
parent: my-project
|
parent: my-project
|
||||||
short_name: fw-policy
|
short_name: fw-policy
|
||||||
|
timeouts: null
|
||||||
module.firewall-policy.google_compute_firewall_policy_association.hierarchical["my-vpc"]:
|
module.firewall-policy.google_compute_firewall_policy_association.hierarchical["my-vpc"]:
|
||||||
name: fw-policy-my-vpc
|
name: fw-policy-my-vpc
|
||||||
|
timeouts: null
|
||||||
module.firewall-policy.google_compute_firewall_policy_rule.hierarchical["ingress/http"]:
|
module.firewall-policy.google_compute_firewall_policy_rule.hierarchical["ingress/http"]:
|
||||||
action: apply_security_profile_group
|
action: apply_security_profile_group
|
||||||
description: null
|
description: null
|
||||||
@@ -54,20 +102,27 @@ values:
|
|||||||
src_ip_ranges:
|
src_ip_ranges:
|
||||||
- 10.0.0.0/8
|
- 10.0.0.0/8
|
||||||
src_region_codes: null
|
src_region_codes: null
|
||||||
|
src_secure_tags: []
|
||||||
src_threat_intelligences: null
|
src_threat_intelligences: null
|
||||||
priority: 1000
|
priority: 1000
|
||||||
target_resources: null
|
target_resources: null
|
||||||
|
target_secure_tags: []
|
||||||
target_service_accounts: null
|
target_service_accounts: null
|
||||||
|
timeouts: null
|
||||||
tls_inspect: null
|
tls_inspect: null
|
||||||
module.vpc.google_compute_network.network[0]:
|
module.vpc.google_compute_network.network[0]:
|
||||||
auto_create_subnetworks: false
|
auto_create_subnetworks: false
|
||||||
|
delete_bgp_always_compare_med: false
|
||||||
delete_default_routes_on_create: false
|
delete_default_routes_on_create: false
|
||||||
description: Terraform-managed.
|
description: Terraform-managed.
|
||||||
enable_ula_internal_ipv6: null
|
enable_ula_internal_ipv6: null
|
||||||
name: my-network
|
name: my-network
|
||||||
network_firewall_policy_enforcement_order: AFTER_CLASSIC_FIREWALL
|
network_firewall_policy_enforcement_order: AFTER_CLASSIC_FIREWALL
|
||||||
|
network_profile: null
|
||||||
|
params: []
|
||||||
project: my-project
|
project: my-project
|
||||||
routing_mode: GLOBAL
|
routing_mode: GLOBAL
|
||||||
|
timeouts: null
|
||||||
module.vpc.google_compute_route.gateway["private-googleapis"]:
|
module.vpc.google_compute_route.gateway["private-googleapis"]:
|
||||||
description: Terraform-managed.
|
description: Terraform-managed.
|
||||||
dest_range: 199.36.153.8/30
|
dest_range: 199.36.153.8/30
|
||||||
@@ -77,9 +132,11 @@ values:
|
|||||||
next_hop_ilb: null
|
next_hop_ilb: null
|
||||||
next_hop_instance: null
|
next_hop_instance: null
|
||||||
next_hop_vpn_tunnel: null
|
next_hop_vpn_tunnel: null
|
||||||
|
params: []
|
||||||
priority: 1000
|
priority: 1000
|
||||||
project: my-project
|
project: my-project
|
||||||
tags: null
|
tags: null
|
||||||
|
timeouts: null
|
||||||
module.vpc.google_compute_route.gateway["restricted-googleapis"]:
|
module.vpc.google_compute_route.gateway["restricted-googleapis"]:
|
||||||
description: Terraform-managed.
|
description: Terraform-managed.
|
||||||
dest_range: 199.36.153.4/30
|
dest_range: 199.36.153.4/30
|
||||||
@@ -89,9 +146,11 @@ values:
|
|||||||
next_hop_ilb: null
|
next_hop_ilb: null
|
||||||
next_hop_instance: null
|
next_hop_instance: null
|
||||||
next_hop_vpn_tunnel: null
|
next_hop_vpn_tunnel: null
|
||||||
|
params: []
|
||||||
priority: 1000
|
priority: 1000
|
||||||
project: my-project
|
project: my-project
|
||||||
tags: null
|
tags: null
|
||||||
|
timeouts: null
|
||||||
|
|
||||||
counts:
|
counts:
|
||||||
google_compute_firewall_policy: 1
|
google_compute_firewall_policy: 1
|
||||||
@@ -99,7 +158,7 @@ counts:
|
|||||||
google_compute_firewall_policy_rule: 1
|
google_compute_firewall_policy_rule: 1
|
||||||
google_compute_network: 1
|
google_compute_network: 1
|
||||||
google_compute_route: 3
|
google_compute_route: 3
|
||||||
google_network_security_security_profile: 1
|
google_network_security_security_profile: 2
|
||||||
google_network_security_security_profile_group: 1
|
google_network_security_security_profile_group: 2
|
||||||
modules: 2
|
modules: 2
|
||||||
resources: 9
|
resources: 11
|
||||||
|
|||||||
88
tests/modules/net_firewall_policy/examples/mirroring.yaml
Normal file
88
tests/modules/net_firewall_policy/examples/mirroring.yaml
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# Copyright 2026 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.default:
|
||||||
|
custom_intercept_profile: []
|
||||||
|
custom_mirroring_profile:
|
||||||
|
- mirroring_deployment_groups: null
|
||||||
|
mirroring_endpoint_group: xxx
|
||||||
|
description: null
|
||||||
|
effective_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
|
labels: null
|
||||||
|
location: global
|
||||||
|
name: sec-profile
|
||||||
|
parent: organizations/1122334455
|
||||||
|
terraform_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
|
threat_prevention_profile: []
|
||||||
|
timeouts: null
|
||||||
|
type: CUSTOM_MIRRORING
|
||||||
|
url_filtering_profile: []
|
||||||
|
google_network_security_security_profile_group.default:
|
||||||
|
custom_intercept_profile: null
|
||||||
|
description: null
|
||||||
|
effective_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
|
labels: null
|
||||||
|
location: global
|
||||||
|
name: sec-profile-group
|
||||||
|
parent: organizations/1122334455
|
||||||
|
terraform_labels:
|
||||||
|
goog-terraform-provisioned: 'true'
|
||||||
|
threat_prevention_profile: null
|
||||||
|
timeouts: null
|
||||||
|
url_filtering_profile: null
|
||||||
|
module.firewall-policy.google_compute_network_firewall_policy.net-global[0]:
|
||||||
|
description: null
|
||||||
|
name: test-mirroring
|
||||||
|
project: my-project
|
||||||
|
timeouts: null
|
||||||
|
module.firewall-policy.google_compute_network_firewall_policy_association.net-global["my-vpc"]:
|
||||||
|
attachment_target: https://www.googleapis.com/compute/v1/projects/xxx/global/networks/aaa
|
||||||
|
firewall_policy: test-mirroring
|
||||||
|
name: test-mirroring-my-vpc
|
||||||
|
project: my-project
|
||||||
|
timeouts: null
|
||||||
|
module.firewall-policy.google_compute_network_firewall_policy_packet_mirroring_rule.net-global["mirror/ingress/rule-1"]:
|
||||||
|
action: mirror
|
||||||
|
description: Mirror all traffic
|
||||||
|
direction: INGRESS
|
||||||
|
disabled: false
|
||||||
|
firewall_policy: test-mirroring
|
||||||
|
match:
|
||||||
|
- dest_ip_ranges: null
|
||||||
|
layer4_configs:
|
||||||
|
- ip_protocol: tcp
|
||||||
|
ports:
|
||||||
|
- '80'
|
||||||
|
- '443'
|
||||||
|
src_ip_ranges:
|
||||||
|
- 0.0.0.0/0
|
||||||
|
priority: 1000
|
||||||
|
project: my-project
|
||||||
|
rule_name: rule-1
|
||||||
|
target_secure_tags: []
|
||||||
|
timeouts: null
|
||||||
|
tls_inspect: null
|
||||||
|
|
||||||
|
counts:
|
||||||
|
google_compute_network_firewall_policy: 1
|
||||||
|
google_compute_network_firewall_policy_association: 1
|
||||||
|
google_compute_network_firewall_policy_packet_mirroring_rule: 1
|
||||||
|
google_network_security_security_profile: 1
|
||||||
|
google_network_security_security_profile_group: 1
|
||||||
|
modules: 1
|
||||||
|
resources: 5
|
||||||
Reference in New Issue
Block a user