Skip to content

Commit 4d3ca19

Browse files
authored
Merge pull request #79 from terraform-google-modules/ludo-firewall-submodule
Add dynamic rules to Fabric firewall submodule
2 parents bc07616 + 52e49a9 commit 4d3ca19

File tree

5 files changed

+134
-3
lines changed

5 files changed

+134
-3
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
terraform.tfvars

modules/fabric-net-firewall/README.md

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,38 @@
1-
# Google Cloud Simple VPC Firewall Creation
1+
# Google Cloud VPC Firewall
22

3-
This module allows creation of a minimal VPC firewall, supporting basic configurable rules for IP range-based intra-VPC and administrator ingress, and tag-based SSH, HTTP, and HTTPS ingress.
3+
This module allows creation of a minimal VPC firewall, supporting basic configurable rules for IP range-based intra-VPC and administrator ingress, tag-based SSH/HTTP/HTTPS ingress, and custom rule definitions.
44

5-
The HTTP and HTTPS rules use the same network tags network tags that are assigned to instances when flaggging the "Allow HTTP[S] traffic" checkbox in the Cloud Console. The SSH rule uses a generic `ssh` tag.
5+
The HTTP and HTTPS rules use the same network tags that are assigned to instances when the "Allow HTTP[S] traffic" checkbox is flagged in the Cloud Console. The SSH rule uses a generic `ssh` tag.
66

77
All IP source ranges are configurable through variables, and are set by default to `0.0.0.0/0` for tag-based rules. Allowed protocols and/or ports for the intra-VPC rule are also configurable through a variable.
88

9+
Custom rules are set through a map where keys are rule names, and values use this custom type:
10+
11+
```hcl
12+
map(object({
13+
description = string
14+
direction = string # (INGRESS|EGRESS)
15+
action = string # (allow|deny)
16+
ranges = list(string) # list of IP CIDR ranges
17+
sources = list(string) # tags or SAs (ignored for EGRESS)
18+
targets = list(string) # tags or SAs
19+
use_service_accounts = bool # use tags or SAs in sources/targets
20+
rules = list(object({
21+
protocol = string
22+
ports = list(string)
23+
}))
24+
extra_attributes = map(string) # map, optional keys disabled or priority
25+
}))
26+
```
27+
928
The resources created/managed by this module are:
1029

1130
- one optional ingress rule from internal CIDR ranges, only allowing ICMP by default
1231
- one optional ingress rule from admin CIDR ranges, allowing all protocols on all ports
1332
- one optional ingress rule for SSH on network tag `ssh`
1433
- one optional ingress rule for HTTP on network tag `http-server`
1534
- one optional ingress rule for HTTPS on network tag `https-server`
35+
- one or more optional custom rules
1636

1737

1838
## Usage
@@ -26,6 +46,24 @@ module "net-firewall" {
2646
network = "my-vpc"
2747
internal_ranges_enabled = true
2848
internal_ranges = ["10.0.0.0/0"]
49+
custom_rules = {
50+
ingress-sample = {
51+
description = "Dummy sample ingress rule, tag-based."
52+
direction = "INGRESS"
53+
action = "allow"
54+
ranges = ["192.168.0.0"]
55+
sources = ["spam-tag"]
56+
targets = ["foo-tag", "egg-tag"]
57+
use_service_accounts = false
58+
rules = [
59+
{
60+
protocol = "tcp"
61+
ports = []
62+
}
63+
]
64+
extra_attributes = {}
65+
}
66+
}
2967
}
3068
```
3169

@@ -36,6 +74,7 @@ module "net-firewall" {
3674
|------|-------------|:----:|:-----:|:-----:|
3775
| admin\_ranges | IP CIDR ranges that have complete access to all subnets. | list | `<list>` | no |
3876
| admin\_ranges\_enabled | Enable admin ranges-based rules. | string | `"false"` | no |
77+
| custom\_rules | List of custom rule definitions (refer to variables file for syntax). | map | `<map>` | no |
3978
| http\_source\_ranges | List of IP CIDR ranges for tag-based HTTP rule, defaults to 0.0.0.0/0. | list | `<list>` | no |
4079
| https\_source\_ranges | List of IP CIDR ranges for tag-based HTTPS rule, defaults to 0.0.0.0/0. | list | `<list>` | no |
4180
| internal\_allow | Allow rules for internal ranges. | list | `<list>` | no |

modules/fabric-net-firewall/main.tf

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,44 @@ resource "google_compute_firewall" "allow-tag-https" {
104104
ports = ["443"]
105105
}
106106
}
107+
108+
################################################################################
109+
# dynamic rules #
110+
################################################################################
111+
112+
resource "google_compute_firewall" "custom" {
113+
# provider = "google-beta"
114+
for_each = var.custom_rules
115+
name = each.key
116+
description = each.value.description
117+
direction = each.value.direction
118+
network = var.network
119+
project = var.project_id
120+
source_ranges = each.value.direction == "INGRESS" ? each.value.ranges : null
121+
destination_ranges = each.value.direction == "EGRESS" ? each.value.ranges : null
122+
source_tags = each.value.use_service_accounts || each.value.direction == "EGRESS" ? null : each.value.sources
123+
source_service_accounts = each.value.use_service_accounts && each.value.direction == "INGRESS" ? each.value.sources : null
124+
target_tags = each.value.use_service_accounts ? null : each.value.targets
125+
target_service_accounts = each.value.use_service_accounts ? each.value.targets : null
126+
disabled = lookup(each.value.extra_attributes, "disabled", false)
127+
priority = lookup(each.value.extra_attributes, "priority", 1000)
128+
# enable_logging = lookup(each.value.extra_attributes, "enable_logging", false)
129+
130+
dynamic "allow" {
131+
for_each = [for rule in each.value.rules : rule if each.value.action == "allow"]
132+
iterator = rule
133+
content {
134+
protocol = rule.value.protocol
135+
ports = rule.value.ports
136+
}
137+
}
138+
139+
dynamic "deny" {
140+
for_each = [for rule in each.value.rules : rule if each.value.action == "deny"]
141+
iterator = rule
142+
content {
143+
protocol = rule.value.protocol
144+
ports = rule.value.ports
145+
}
146+
}
147+
}

modules/fabric-net-firewall/outputs.tf

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,34 @@ output "admin_ranges" {
3232
}
3333
}
3434

35+
output "custom_ingress_allow_rules" {
36+
description = "Custom ingress rules with allow blocks."
37+
value = [
38+
for rule in google_compute_firewall.custom :
39+
rule.name if rule.direction == "INGRESS" && length(rule.allow) > 0
40+
]
41+
}
42+
43+
output "custom_ingress_deny_rules" {
44+
description = "Custom ingress rules with deny blocks."
45+
value = [
46+
for rule in google_compute_firewall.custom :
47+
rule.name if rule.direction == "INGRESS" && length(rule.deny) > 0
48+
]
49+
}
50+
51+
output "custom_egress_allow_rules" {
52+
description = "Custom egress rules with allow blocks."
53+
value = [
54+
for rule in google_compute_firewall.custom :
55+
rule.name if rule.direction == "EGRESS" && length(rule.allow) > 0
56+
]
57+
}
58+
59+
output "custom_egress_deny_rules" {
60+
description = "Custom egress rules with allow blocks."
61+
value = [
62+
for rule in google_compute_firewall.custom :
63+
rule.name if rule.direction == "EGRESS" && length(rule.deny) > 0
64+
]
65+
}

modules/fabric-net-firewall/variables.tf

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,22 @@ variable "https_source_ranges" {
6565
description = "List of IP CIDR ranges for tag-based HTTPS rule, defaults to 0.0.0.0/0."
6666
default = ["0.0.0.0/0"]
6767
}
68+
69+
variable "custom_rules" {
70+
description = "List of custom rule definitions (refer to variables file for syntax)."
71+
default = {}
72+
type = map(object({
73+
description = string
74+
direction = string
75+
action = string # (allow|deny)
76+
ranges = list(string)
77+
sources = list(string)
78+
targets = list(string)
79+
use_service_accounts = bool
80+
rules = list(object({
81+
protocol = string
82+
ports = list(string)
83+
}))
84+
extra_attributes = map(string)
85+
}))
86+
}

0 commit comments

Comments
 (0)