# Google Cloud VPC Firewall
This module allows creation and management of different types of firewall rules for a single VPC network:
- custom rules via the `egress_rules` and `ingress_rules` variables
- optional predefined rules that simplify prototyping via the `default_rules_config` variable
The predefined rules are enabled by default and set to the ranges of the GCP health checkers for HTTP/HTTPS, and the IAP forwarders for SSH. See the relevant section below on how to configure or disable them.
## Examples
### Minimal open firewall
This is often useful for prototyping or testing infrastructure, allowing open ingress from the private range, enabling SSH to private addresses from IAP, and HTTP/HTTPS from the health checkers.
```hcl
module "firewall" {
source = "./fabric/modules/net-vpc-firewall"
project_id = "my-project"
network = "my-network"
default_rules_config = {
admin_ranges = ["10.0.0.0/8"]
}
}
# tftest modules=1 resources=4
```
### Custom rules
This is an example of how to define custom rules, with a sample rule allowing open ingress for the NTP protocol to instances with the `ntp-svc` tag.
Some implicit defaults are used in the rules variable types and can be controlled by explicitly setting specific attributes:
- action is controlled via the `deny` attribute which defaults to `true` for egress and `false` for ingress
- priority defaults to `1000`
- destination ranges (for egress) and source ranges (for ingress) default to `["0.0.0.0/0"]` if not explicitly set
- rules default to all protocols if not set
```hcl
module "firewall" {
source = "./fabric/modules/net-vpc-firewall"
project_id = "my-project"
network = "my-network"
default_rules_config = {
admin_ranges = ["10.0.0.0/8"]
}
egress_rules = {
# implicit `deny` action
allow-egress-rfc1918 = {
description = "Allow egress to RFC 1918 ranges."
destination_ranges = [
"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"
]
# implicit { protocol = "all" } rule
}
deny-egress-all = {
description = "Block egress."
# implicit ["0.0.0.0/0"] destination ranges
# implicit { protocol = "all" } rule
}
}
ingress_rules = {
# implicit `allow` action
allow-ingress-ntp = {
description = "Allow NTP service based on tag."
source_ranges = ["0.0.0.0/0"]
targets = ["ntp-svc"]
rules = [{ protocol = "udp", ports = [123] }]
}
}
}
# tftest modules=1 resources=7
```
### Controlling or turning off default rules
Predefined rules can be controlled or turned off via the `default_rules_config` variable.
#### Overriding default tags and ranges
Each protocol rule has a default set of tags and ranges:
- the health check range and the `http-server`/`https-server` tag for HTTP/HTTPS, matching tags set via GCP console flags on GCE instances
- the IAP forwarders range and `ssh` tag for SSH
Default tags and ranges can be overridden for each protocol, like shown here for SSH:
```hcl
module "firewall" {
source = "./fabric/modules/net-vpc-firewall"
project_id = "my-project"
network = "my-network"
default_rules_config = {
ssh_ranges = ["10.0.0.0/8"]
ssh_rags = ["ssh-default"]
}
}
# tftest modules=1 resources=3
```
#### Disabling predefined rules
Default rules can be disabled individually by specifying an empty set of ranges:
```hcl
module "firewall" {
source = "./fabric/modules/net-vpc-firewall"
project_id = "my-project"
network = "my-network"
default_rules_config = {
ssh_ranges = []
}
}
# tftest modules=1 resources=2
```
Or the entire set of rules can be disabled via the `disabled` attribute:
```hcl
module "firewall" {
source = "./fabric/modules/net-vpc-firewall"
project_id = "my-project"
network = "my-network"
default_rules_config = {
disabled = true
}
}
# tftest modules=0 resources=0
```
### Rules Factory
The module includes a rules factory (see [Resource Factories](../../blueprints/factories/)) for the massive creation of rules leveraging YaML configuration files. Each configuration file can optionally contain more than one rule which a structure that reflects the `custom_rules` variable.
```hcl
module "firewall" {
source = "./fabric/modules/net-vpc-firewall"
project_id = "my-project"
network = "my-network"
factories_config = {
rules_folder = "configs/firewal/rules"
cidr_tpl_file = "configs/firewal/cidr_template.yaml"
}
}
# tftest modules=1 resources=3
```
```yaml
# tftest file configs/firewall/rules/load_balancers.yaml
allow-healthchecks:
description: Allow ingress from healthchecks.
ranges:
- healthchecks
targets: ["lb-backends"]
rules:
- protocol: tcp
ports:
- 80
- 443
```
```yaml
# tftest file configs/firewall/cidr_template.yaml
healthchecks:
- 35.191.0.0/16
- 130.211.0.0/22
- 209.85.152.0/22
- 209.85.204.0/22
```
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [network](variables.tf#L109) | Name of the network this set of firewall rules applies to. | string
| ✓ | |
| [project_id](variables.tf#L114) | Project id of the project that holds the network. | string
| ✓ | |
| [default_rules_config](variables.tf#L17) | Optionally created convenience rules. Set the variable or individual members to null to disable. | object({…})
| | {}
|
| [egress_rules](variables.tf#L37) | List of egress rule definitions, default to deny action. | map(object({…}))
| | {}
|
| [factories_config](variables.tf#L83) | Paths to data files and folders that enable factory functionality. | object({…})
| | null
|
| [ingress_rules](variables.tf#L60) | List of ingress rule definitions, default to allow action. | map(object({…}))
| | {}
|
| [named_ranges](variables.tf#L92) | Define mapping of names to ranges that can be used in custom rules. | map(list(string))
| | {…}
|
## Outputs
| name | description | sensitive |
|---|---|:---:|
| [default_rules](outputs.tf#L17) | Default rule resources. | |
| [rules](outputs.tf#L27) | Custom rule resources. | |