Files
hunfabric/modules/net-firewall-policy
Ludovico Magnocavallo 36648b6b63 FAST light implementation (#3255)
* data wip

* wip data

* update org schema, add note on expansion

* all schemas, workload notes

* Update WORKLOG.md

* Update WORKLOG.md

* Update WORKLOG.md

* Update WORKLOG.md

* wip

* data wip

* wip

* wip

* wip

* wip

* org module IAM context (using lookup)

* new-style context expansion in project IAM

* remove spurious file

* project module contexts

* finalize context replacement format for project module

* revert org module changes

* fix tag id interpolation in project

* fix tag id interpolation in project

* organization module context

* organization context test

* context expansion for folder tag bindings

* test context expansion for tag bindings

* service account module context

* simplify context local

* context for iam service account

* nuke blueprints

* remove links to blueprints

* vpc sc context in project module

* Add context to GCS module

* Add inline deps to plan_summary script

* Make context a top-level variable for folder, organization, sa

* Add add context top-level to VPC-SC

* move context out of factories_config variable

* tfdoc

* fix merge

* fix merge

* fix examples

* net-vpc module context

* add parent ids to folder context

* rename folder parent context

* fix folder parent check

* new project factory stub

* wip

* wip

* refactor defaults

* project iam

* bueckts and service accounts

* start adding context replacements

* better test data

* automation resources for folders and projects

* automation

* add support for project id interpolation

* first tested apply

* improve IAM description in gcs module

* add context to billing account module

* add notification channels to billing account module context

* add billing budgets to new pf

* schemas and defaults

* bootstrap wip

* bootstrap wip

* bootstrap wip

* pf outputs

* pf fixes

* fix pf sample data

* bootstrap lite fixes

* add locations to organization module contexts

* bootstrap lite fixes

* org fixes, billing accounts

* fix default project parent

* bootstrap lite wip

* add locations to gcs module context

* add context support to logging bucket module

* add context to pubsub module

* split out iam variables in gcs module

* fix logging bucket context test

* bootstrap log sink destinations

* streamline logging-bucket module variables

* fix logging bucket context test

* align logging bucket module interface in fast bootstrap

* add support for project-level log buckets to project factory

* support full context expansion in organization module log sinks

* log buckets in fast-lite bootstrap

* make og sink type optional in organization module

* log sinks in fast-lite bootstrap

* set tag values in factory context

* bootstrap lite data

* output files schema

* billing account schema

* output files

* output providers

* gcs output files

* boilerplate

* tflint

* check documentation

* check docs

* fix project module parent variable validation

* fix log bucket examples

* allow null parent in project module

* silence folder test errors

* fix billing account sink example

* fix project example

* fix billing account module

* fix folder tests

* fix FAST

* fix fast

* tfvars outputs

* wif

* cicd service accounts

* cicd

* allow defaults in context, minimal org policies

* support gcs managed folders in project factory and bootstrap lite

* support prefix in provider output files

* rename bootstrap stage

* gitignore

* gitignore

* security folder, billing IAM

* wip tfvars

* fix typo

* security IAM

* control tag iam/context via variables in organization module

* split tag creation from tag IAM to avoid circular refs

* port organization module tag changes to project module

* implement new-style context expansion in vpc-sc module

* fix fast vpc-sc tests

* boilerplate

* vpc sc stage

* schemas

* fast-lite compatibility for vpc sc stage

* make log project number optional in vpc-sc stage

* networking

* networking

* networking

* networking

* rename and move new stage under fast

* clone pf tests

* use context replacement for internal notification channels in billing account module

* support service agents in project module iam context replacements

* support service agents in project module iam context replacements

* add support for kms keys to project module context

* experimental pf example test and fixes

* fix schemas

* fix tests

* tfdoc

* tfdoc

* pf config

* experimental pf

* remove redundant dot from gcs managed folder IAM keys

* bootstrap experimental test

* project factory exp stage test

* skip tflint for bootstrap experimental test

* tflint

* fix gcs test

* documentation work

* documentation work

* Update README.md

* tfdoc

* tfdoc

* readme

* tfdoc

* readme

* readme

* readme

* readme

* support universe in pf exp projects

* missing universe service agents

* org policies import, non-admin billing IAM

* todo

* fix test

* custom constraints

* fast classic dataset

* fix test data

* context replacements in billing module log sinks

* fix typo

* add support for billing log sinks

* update docs

* readme

* cicd fix and test

---------

Co-authored-by: Julio Castillo <jccb@google.com>
2025-09-02 08:38:57 +02:00
..
2024-04-17 10:23:48 +02:00
2025-09-02 08:38:57 +02:00

Firewall Policies

This module allows creation and management of two different firewall policy types:

The module also manages policy rules via code or a factory, and optional policy attachments. The interface deviates slightly from the net-vpc-firewall module since the underlying resources and API objects are different.

The module also makes fewer assumptions about implicit defaults, only using one to set match.layer4_configs to [{ protocol = "all" }] if no explicit set of protocols and ports has been specified.

Examples

Hierarchical Policy

module "firewall-policy" {
  source    = "./fabric/modules/net-firewall-policy"
  name      = "test-1"
  parent_id = "folders/1234567890"
  attachments = {
    test = "folders/4567890123"
  }
  egress_rules = {
    smtp = {
      priority = 900
      match = {
        destination_ranges = ["0.0.0.0/0"]
        layer4_configs     = [{ protocol = "tcp", ports = ["25"] }]
      }
    }
  }
  ingress_rules = {
    icmp = {
      priority = 1000
      match = {
        source_ranges  = ["0.0.0.0/0"]
        layer4_configs = [{ protocol = "icmp" }]
      }
    }
    mgmt = {
      priority       = 1001
      enable_logging = true
      match = {
        source_ranges = ["10.1.1.0/24"]
      }
    }
    ssh = {
      priority       = 1002
      enable_logging = true
      match = {
        source_ranges = ["10.0.0.0/8"]
        # source_tags    = ["tagValues/123456"]
        layer4_configs = [{ protocol = "tcp", ports = ["22"] }]
      }
    }
  }
}
# tftest modules=1 resources=6 inventory=hierarchical.yaml

Global Network policy

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "my-network"
}

module "firewall-policy" {
  source    = "./fabric/modules/net-firewall-policy"
  name      = "test-1"
  parent_id = "my-project"
  region    = "global"
  attachments = {
    my-vpc = module.vpc.self_link
  }
  egress_rules = {
    smtp = {
      priority = 900
      match = {
        destination_ranges = ["0.0.0.0/0"]
        layer4_configs     = [{ protocol = "tcp", ports = ["25"] }]
      }
    }
  }
  ingress_rules = {
    icmp = {
      priority = 1000
      match = {
        source_ranges  = ["0.0.0.0/0"]
        layer4_configs = [{ protocol = "icmp" }]
      }
    }
    mgmt = {
      priority       = 1001
      enable_logging = true
      match = {
        source_ranges = ["10.1.1.0/24"]
      }
    }
    ssh = {
      priority       = 1002
      enable_logging = true
      match = {
        source_ranges = ["10.0.0.0/8"]
        # source_tags    = ["tagValues/123456"]
        layer4_configs = [{ protocol = "tcp", ports = ["22"] }]
      }
    }
  }
}
# tftest modules=2 resources=10 inventory=global-net.yaml

Regional Network policy

module "vpc" {
  source     = "./fabric/modules/net-vpc"
  project_id = "my-project"
  name       = "my-network"
}

module "firewall-policy" {
  source    = "./fabric/modules/net-firewall-policy"
  name      = "test-1"
  parent_id = "my-project"
  region    = "europe-west8"
  attachments = {
    my-vpc = module.vpc.self_link
  }
  egress_rules = {
    smtp = {
      priority = 900
      match = {
        destination_ranges = ["0.0.0.0/0"]
        layer4_configs     = [{ protocol = "tcp", ports = ["25"] }]
      }
    }
  }
  ingress_rules = {
    icmp = {
      priority = 1000
      match = {
        source_ranges  = ["0.0.0.0/0"]
        layer4_configs = [{ protocol = "icmp" }]
      }
    }
  }
}
# tftest modules=2 resources=8 inventory=regional-net.yaml

Factory

Similarly to other modules, a rules factory is also included here to allow route management via descriptive configuration files.

Factory configuration is via three optional attributes in the rules_factory_config variable:

  • 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
  • ingress_rules_file_path specifying the path to the ingress rules file

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.

This is an example of a simple factory:

module "firewall-policy" {
  source    = "./fabric/modules/net-firewall-policy"
  name      = "test-1"
  parent_id = "folders/1234567890"
  attachments = {
    test = "folders/4567890123"
  }
  ingress_rules = {
    ssh = {
      priority = 1002
      match = {
        source_ranges  = ["10.0.0.0/8"]
        layer4_configs = [{ protocol = "tcp", ports = ["22"] }]
      }
    }
  }
  factories_config = {
    cidr_file_path          = "configs/cidrs.yaml"
    egress_rules_file_path  = "configs/egress.yaml"
    ingress_rules_file_path = "configs/ingress.yaml"
  }
}
# tftest modules=1 resources=6 files=cidrs,egress,ingress inventory=factory.yaml
rfc1918:
  - 10.0.0.0/8
  - 172.16.0.0/12
  - 192.168.0.0/24
gke-nodes-range:
  - 10.0.1.0/24
# tftest-file id=cidrs path=configs/cidrs.yaml
smtp:
  priority: 900
  match:
   destination_ranges:
   - rfc1918
   layer4_configs:
   - protocol: tcp
     ports:
     - 25
# tftest-file id=egress path=configs/egress.yaml schema=firewall-policy-rules.schema.json
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.

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=9 files=ingress-spg inventory=factory-spg.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

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.

rule-name:
  priority:
  action:
  description:
  disabled:
  enable_logging:
  security_profile_group: # Not for Regional policies
  target_service_accounts: []
  target_tags: [] # Not for Hierarchical policies
  target_resources: [] # For Hierarchical policies only
  tls_inspect: # Not for Regional policies
  match:
    source_ranges: []
    destination_ranges: []
    source_tags: [] # Not for Hierarchical policies
    threat_intelligences: []
    fqdns: []
    address_groups: []
    region_codes: []
    layer4_configs:
      - protocol:
        ports: []

Dynamic Rule Matching

This module simplifies firewall rule creation by using generic, context-aware variables within the match block. Based on the rule's specified direction (INGRESS or EGRESS), the module maps these generic variables to the correct source- (src_*) or destination-specific (dest_*) arguments in the underlying resource.

The tables below provide a complete reference for these dynamic mappings.

Ingress Rules (direction = "INGRESS")

Module Variable (match.*) Mapped Resource Attribute
address_groups src_address_groups
fqdns src_fqdns
region_codes src_region_codes
source_tags src_secure_tags
threat_intelligences src_threat_intelligences

Egress Rules (direction = "EGRESS")

Module Variable (match.*) Mapped Resource Attribute
address_groups dest_address_groups
fqdns dest_fqdns
region_codes dest_region_codes
threat_intelligences dest_threat_intelligences

Rule-Level Mappings

The following variable is defined at the top level of the rule (not within the match block) and is mapped directly, regardless of the rule's direction.

Module Variable Mapped Resource Attribute
target_tags target_secure_tags

Variables

name description type required default
name Policy name. string
parent_id Parent node where the policy will be created, folders/nnn or organizations/nnn for hierarchical policy, project id for a network policy. string
attachments 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. map(string) {}
description Policy description. string null
egress_rules 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. map(object({…})) {}
factories_config Paths to folders for the optional factories. object({…}) {}
ingress_rules List of ingress rule definitions, action can be 'allow', 'deny', 'goto_next' or 'apply_security_profile_group'. map(object({…})) {}
region Policy region. Leave null for hierarchical policy, set to 'global' for a global network policy. string null
security_profile_group_ids The optional security groups ids to be referenced in factories. map(string) {}

Outputs

name description sensitive
id Fully qualified firewall policy id.