Allow using named ranges in firewall rules

This commit is contained in:
Julio Castillo 2021-10-04 12:39:45 +02:00
parent d3e8b5e35e
commit 400a94658d
3 changed files with 98 additions and 44 deletions

View File

@ -53,6 +53,36 @@ module "firewall" {
# tftest:modules=1:resources=5
```
### No predefined rules
If you don't want any predefined rules, `admin_ranges_enabled` to `false` and `http_source_ranges`, `https_source_ranges`, `ssh_source_ranges` to an empty list.
```hcl
module "firewall" {
source = "./modules/net-vpc-firewall"
project_id = "my-project"
network = "my-network"
admin_ranges_enabled = false
http_source_ranges = []
https_source_ranges = []
ssh_source_ranges = []
custom_rules = {
allow-https = {
description = "Allow HTTPS from internal networks."
direction = "INGRESS"
action = "allow"
sources = []
ranges = ["rfc1918"]
targets = []
use_service_accounts = false
rules = [{ protocol = "tcp", ports = [443] }]
extra_attributes = {}
}
}
}
# tftest:modules=1:resources=1
```
<!-- BEGIN TFDOC -->
## Variables
@ -65,6 +95,7 @@ module "firewall" {
| *custom_rules* | List of custom rule definitions (refer to variables file for syntax). | <code title="map&#40;object&#40;&#123;&#10;description &#61; string&#10;direction &#61; string&#10;action &#61; string &#35; &#40;allow&#124;deny&#41;&#10;ranges &#61; list&#40;string&#41;&#10;sources &#61; list&#40;string&#41;&#10;targets &#61; list&#40;string&#41;&#10;use_service_accounts &#61; bool&#10;rules &#61; list&#40;object&#40;&#123;&#10;protocol &#61; string&#10;ports &#61; list&#40;string&#41;&#10;&#125;&#41;&#41;&#10;extra_attributes &#61; map&#40;string&#41;&#10;&#125;&#41;&#41;">map(object({...}))</code> | | <code title="">{}</code> |
| *http_source_ranges* | List of IP CIDR ranges for tag-based HTTP rule, defaults to the health checkers ranges. | <code title="list&#40;string&#41;">list(string)</code> | | <code title="">["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"]</code> |
| *https_source_ranges* | List of IP CIDR ranges for tag-based HTTPS rule, defaults to the health checkers ranges. | <code title="list&#40;string&#41;">list(string)</code> | | <code title="">["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"]</code> |
| *named_ranges* | Names that can be used of valid values for the `ranges` field of `custom_rules` | <code title="map&#40;list&#40;string&#41;&#41;">map(list(string))</code> | | <code title="&#123;&#10;dns-forwarders &#61; &#91;&#34;35.199.192.0&#47;19&#34;&#93;&#10;health-checkers &#61; &#91;&#34;35.191.0.0&#47;16&#34;, &#34;130.211.0.0&#47;22&#34;, &#34;209.85.152.0&#47;22&#34;, &#34;209.85.204.0&#47;22&#34;&#93;&#10;iap-forwarders &#61; &#91;&#34;35.235.240.0&#47;20&#34;&#93;&#10;private-googleapis &#61; &#91;&#34;199.36.153.8&#47;30&#34;&#93;&#10;restricted-googleapis &#61; &#91;&#34;199.36.153.4&#47;30&#34;&#93;&#10;rfc1918 &#61; &#91;&#34;10.0.0.0&#47;8&#34;, &#34;172.16.0.0&#47;12&#34;, &#34;192.168.0.0&#47;16&#34;&#93;&#10;&#125;">...</code> |
| *ssh_source_ranges* | List of IP CIDR ranges for tag-based SSH rule, defaults to the IAP forwarders range. | <code title="list&#40;string&#41;">list(string)</code> | | <code title="">["35.235.240.0/20"]</code> |
## Outputs
@ -76,5 +107,5 @@ module "firewall" {
| custom_egress_deny_rules | Custom egress rules with allow blocks. | |
| custom_ingress_allow_rules | Custom ingress rules with allow blocks. | |
| custom_ingress_deny_rules | Custom ingress rules with deny blocks. | |
| rules | All google_compute_firewall resources created | |
| rules | All google_compute_firewall resources created. | |
<!-- END TFDOC -->

View File

@ -14,6 +14,21 @@
* limitations under the License.
*/
locals {
custom_rules = {
for id, rule in var.custom_rules :
id => merge(rule, {
# make rules a map so we use it in a for_each
rules = { for index, ports in rule.rules : index => ports }
# lookup any named ranges references
ranges = flatten([
for range in rule.ranges :
try(var.named_ranges[range], range)
])
})
}
}
###############################################################################
# rules based on IP ranges
###############################################################################
@ -80,7 +95,7 @@ resource "google_compute_firewall" "allow-tag-https" {
resource "google_compute_firewall" "custom-rules" {
# provider = "google-beta"
for_each = var.custom_rules
for_each = local.custom_rules
name = each.key
description = each.value.description
direction = each.value.direction
@ -104,11 +119,8 @@ resource "google_compute_firewall" "custom-rules" {
}
dynamic "deny" {
for_each = (
each.value.action == "deny"
? { for index, rule in each.value.rules : index => rule }
: {}
)
for_each = each.value.action == "deny" ? each.value.rules : {}
iterator = rule
content {
protocol = rule.value.protocol
@ -117,11 +129,8 @@ resource "google_compute_firewall" "custom-rules" {
}
dynamic "allow" {
for_each = (
each.value.action == "allow"
? { for index, rule in each.value.rules : index => rule }
: {}
)
for_each = each.value.action == "allow" ? each.value.rules : {}
iterator = rule
content {
protocol = rule.value.protocol

View File

@ -14,44 +14,16 @@
* limitations under the License.
*/
variable "network" {
description = "Name of the network this set of firewall rules applies to."
type = string
}
variable "project_id" {
description = "Project id of the project that holds the network."
type = string
}
variable "admin_ranges_enabled" {
description = "Enable admin ranges-based rules."
type = bool
default = false
}
variable "admin_ranges" {
description = "IP CIDR ranges that have complete access to all subnets."
type = list(string)
default = []
}
variable "ssh_source_ranges" {
description = "List of IP CIDR ranges for tag-based SSH rule, defaults to the IAP forwarders range."
type = list(string)
default = ["35.235.240.0/20"]
}
variable "http_source_ranges" {
description = "List of IP CIDR ranges for tag-based HTTP rule, defaults to the health checkers ranges."
type = list(string)
default = ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"]
}
variable "https_source_ranges" {
description = "List of IP CIDR ranges for tag-based HTTPS rule, defaults to the health checkers ranges."
type = list(string)
default = ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"]
variable "admin_ranges_enabled" {
description = "Enable admin ranges-based rules."
type = bool
default = false
}
variable "custom_rules" {
@ -72,3 +44,45 @@ variable "custom_rules" {
}))
default = {}
}
variable "http_source_ranges" {
description = "List of IP CIDR ranges for tag-based HTTP rule, defaults to the health checkers ranges."
type = list(string)
default = ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"]
}
variable "https_source_ranges" {
description = "List of IP CIDR ranges for tag-based HTTPS rule, defaults to the health checkers ranges."
type = list(string)
default = ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"]
}
variable "named_ranges" {
description = "Names that can be used of valid values for the `ranges` field of `custom_rules`"
type = map(list(string))
default = {
any = ["0.0.0.0/0"]
dns-forwarders = ["35.199.192.0/19"]
health-checkers = ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"]
iap-forwarders = ["35.235.240.0/20"]
private-googleapis = ["199.36.153.8/30"]
restricted-googleapis = ["199.36.153.4/30"]
rfc1918 = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]
}
}
variable "network" {
description = "Name of the network this set of firewall rules applies to."
type = string
}
variable "project_id" {
description = "Project id of the project that holds the network."
type = string
}
variable "ssh_source_ranges" {
description = "List of IP CIDR ranges for tag-based SSH rule, defaults to the IAP forwarders range."
type = list(string)
default = ["35.235.240.0/20"]
}