Skip to content

Latest commit

 

History

History
 
 

net-firewall-policy

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=9 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=7 inventory=regional-net.yaml

Factory

Similarly to other modules, a rules factory (see Resource Factories) 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.

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
# tftest-file id=cidrs path=configs/cidrs.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=egress path=configs/egress.yaml
smtp:
  priority: 900
  match:
   destination_ranges:
   - rfc1918
   layer4_configs:
   - protocol: tcp
     ports:
     - 25
# tftest-file id=ingress path=configs/ingress.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:
  - [email protected]
  match:
    source_ranges:
    - gke-nodes-range
    layer4_configs:
    - protocol: tcp
      ports:
      - 1-65535
    - protocol: udp
      ports:
      - 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.

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
# 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

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.