* 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>
Firewall Policies
This module allows creation and management of two different firewall policy types:
- a hierarchical policy in a folder or organization, or
- a global or regional network policy
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_pathspecifying the path to a mapping of logical names to CIDR ranges, used for source and destination ranges in rules when availableegress_rules_file_pathspecifying the path to the egress rules fileingress_rules_file_pathspecifying 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. |